Compare commits
75 Commits
feature/co
...
@portaljs/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b548dfd113 | ||
|
|
c5ee257d48 | ||
|
|
8d83f3a900 | ||
|
|
add2f6d0f3 | ||
|
|
dfab6aa318 | ||
|
|
f96fb562fe | ||
|
|
c4bf5bd054 | ||
|
|
c706575ae4 | ||
|
|
ed8de380a9 | ||
|
|
33521916d6 | ||
|
|
04206457a4 | ||
|
|
8a5acb7012 | ||
|
|
32493a2014 | ||
|
|
b34220cac7 | ||
|
|
44b37e27d9 | ||
|
|
6d3e571151 | ||
|
|
0e997f71e5 | ||
|
|
4a41d517ee | ||
|
|
c79b69ffe6 | ||
|
|
2ad6551a44 | ||
|
|
5de9888c02 | ||
|
|
5a517d714a | ||
|
|
746c77de11 | ||
|
|
9e256b9bf1 | ||
|
|
4bfcd4373b | ||
|
|
6649f78459 | ||
|
|
6f0da8c3a3 | ||
|
|
5b1238cc27 | ||
|
|
17803f1f5d | ||
|
|
81f50bb9a2 | ||
|
|
f1aee6a93e | ||
|
|
053005d784 | ||
|
|
2f5dd4d0f7 | ||
|
|
fb7ce8723a | ||
|
|
7636c3d26c | ||
|
|
6bf6c8faf4 | ||
|
|
095eba606e | ||
|
|
1097b5077d | ||
|
|
aa365cbb0d | ||
|
|
038427874a | ||
|
|
bdfdb2e6a5 | ||
|
|
95b3fc03d3 | ||
|
|
6aeadd71de | ||
|
|
affca05058 | ||
|
|
f54d238795 | ||
|
|
e82e2ae021 | ||
|
|
c3246ee7f8 | ||
|
|
40d80d2282 | ||
|
|
e0e720338f | ||
|
|
4f8b1b1e96 | ||
|
|
362afcc133 | ||
|
|
c165b3cc44 | ||
|
|
261a2a081e | ||
|
|
d27857f490 | ||
|
|
b3ba263bd8 | ||
|
|
cb774d0ad0 | ||
|
|
b48f71ecef | ||
|
|
07b3235647 | ||
|
|
d0c2ee1e71 | ||
|
|
bc180189cb | ||
|
|
39c862627d | ||
|
|
b7158a5be6 | ||
|
|
ee87c4f623 | ||
|
|
4141af0e82 | ||
|
|
7d36d22671 | ||
|
|
eab2d65113 | ||
|
|
51d0a7692e | ||
|
|
cdd90ac384 | ||
|
|
dcf6400304 | ||
|
|
247b2412d6 | ||
|
|
1ad9b85e02 | ||
|
|
af134cac8b | ||
|
|
0b8c56bcac | ||
|
|
20c64222c1 | ||
|
|
683159da02 |
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@portaljs/components': patch
|
||||
---
|
||||
|
||||
More params added to <LineChart />, loading spinners added to <Table /> and <LineChart />, minor fixes
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
||||
dist
|
||||
tmp
|
||||
/out-tsc
|
||||
**/*.tgz
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
160
examples/ckan-ssg/package-lock.json
generated
160
examples/ckan-ssg/package-lock.json
generated
@@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@portaljs/ckan": "^0.0.2",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"next": "13.3.1",
|
||||
"next-seo": "^6.0.0",
|
||||
"octokit": "^2.0.14",
|
||||
@@ -35,7 +36,6 @@
|
||||
"version": "7.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
|
||||
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.13.11"
|
||||
},
|
||||
@@ -732,6 +732,16 @@
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@portaljs/remark-wiki-link": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@portaljs/remark-wiki-link/-/remark-wiki-link-1.0.4.tgz",
|
||||
"integrity": "sha512-cp6vlssDAPawcBI0vUPRpcPdORql3RbK1Q+t1LuRvMQ+yiRb+9DnSPBUviDXKqwsBMOOXP/ePAdYohaeXGt0lQ==",
|
||||
"dependencies": {
|
||||
"mdast-util-to-markdown": "^1.5.0",
|
||||
"mdast-util-wiki-link": "^0.0.2",
|
||||
"micromark-util-symbol": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@rushstack/eslint-patch": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
|
||||
@@ -1420,6 +1430,24 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/character-entities-legacy": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
|
||||
"integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/character-reference-invalid": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
|
||||
"integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
@@ -2888,6 +2916,28 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-alphabetical": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
|
||||
"integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/is-alphanumerical": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
|
||||
"integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
|
||||
"dependencies": {
|
||||
"is-alphabetical": "^1.0.0",
|
||||
"is-decimal": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arguments": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
||||
@@ -3019,6 +3069,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-decimal": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
|
||||
"integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/is-docker": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
||||
@@ -3055,6 +3114,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-hexadecimal": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
|
||||
"integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/is-map": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
|
||||
@@ -3727,6 +3795,59 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-wiki-link": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-wiki-link/-/mdast-util-wiki-link-0.0.2.tgz",
|
||||
"integrity": "sha512-lSsR10/dPuYIxzjGZIGA4oYzsnEnqcsD6DTXL0pqdbBzNB9teKVZB2aIzZcUsdg31v/NoHOstkVwzbN6VrQLtw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"mdast-util-to-markdown": "^0.6.5"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-wiki-link/node_modules/longest-streak": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz",
|
||||
"integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-wiki-link/node_modules/mdast-util-to-markdown": {
|
||||
"version": "0.6.5",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz",
|
||||
"integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==",
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.0",
|
||||
"longest-streak": "^2.0.0",
|
||||
"mdast-util-to-string": "^2.0.0",
|
||||
"parse-entities": "^2.0.0",
|
||||
"repeat-string": "^1.0.0",
|
||||
"zwitch": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-wiki-link/node_modules/mdast-util-to-string": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz",
|
||||
"integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-wiki-link/node_modules/zwitch": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz",
|
||||
"integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
@@ -4714,6 +4835,32 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
|
||||
"integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
|
||||
"dependencies": {
|
||||
"character-entities": "^1.0.0",
|
||||
"character-entities-legacy": "^1.0.0",
|
||||
"character-reference-invalid": "^1.0.0",
|
||||
"is-alphanumerical": "^1.0.0",
|
||||
"is-decimal": "^1.0.0",
|
||||
"is-hexadecimal": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-entities/node_modules/character-entities": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
|
||||
"integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
@@ -5083,8 +5230,7 @@
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
||||
},
|
||||
"node_modules/regexp.prototype.flags": {
|
||||
"version": "1.5.0",
|
||||
@@ -5147,6 +5293,14 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/repeat-string": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
|
||||
"integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@portaljs/ckan": "^0.0.2",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"next": "13.3.1",
|
||||
"next-seo": "^6.0.0",
|
||||
"octokit": "^2.0.14",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MDXRemote } from 'next-mdx-remote';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Mermaid } from '@flowershow/core';
|
||||
import { Mermaid } from '@portaljs/core';
|
||||
|
||||
// Custom components/renderers to pass to MDX.
|
||||
// Since the MDX files aren't loaded by webpack, they have no knowledge of how
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import matter from "gray-matter";
|
||||
import mdxmermaid from "mdx-mermaid";
|
||||
import { h } from "hastscript";
|
||||
import remarkCallouts from "@flowershow/remark-callouts";
|
||||
import remarkEmbed from "@flowershow/remark-embed";
|
||||
import remarkCallouts from "@portaljs/remark-callouts";
|
||||
import remarkEmbed from "@portaljs/remark-embed";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import remarkMath from "remark-math";
|
||||
import remarkSmartypants from "remark-smartypants";
|
||||
import remarkToc from "remark-toc";
|
||||
import remarkWikiLink from "@flowershow/remark-wiki-link";
|
||||
import remarkWikiLink from "@portaljs/remark-wiki-link";
|
||||
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
||||
import rehypeKatex from "rehype-katex";
|
||||
import rehypeSlug from "rehype-slug";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MarkdownDB } from "@flowershow/markdowndb";
|
||||
import { MarkdownDB } from "mddb";
|
||||
|
||||
const dbPath = "markdown.db";
|
||||
|
||||
|
||||
1099
examples/ckan/package-lock.json
generated
1099
examples/ckan/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,14 +11,14 @@
|
||||
"mddb": "mddb ./content"
|
||||
},
|
||||
"dependencies": {
|
||||
"@flowershow/core": "^0.4.13",
|
||||
"@flowershow/markdowndb": "^0.1.5",
|
||||
"@flowershow/remark-callouts": "^1.0.0",
|
||||
"@flowershow/remark-embed": "^1.0.0",
|
||||
"@githubocto/flat-ui": "^0.14.1",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"@portaljs/ckan": "^0.0.2",
|
||||
"@portaljs/components": "0.1.6",
|
||||
"@portaljs/core": "^1.0.5",
|
||||
"@portaljs/remark-callouts": "^1.0.5",
|
||||
"@portaljs/remark-embed": "^1.0.4",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@types/node": "20.2.3",
|
||||
"@types/react": "18.2.6",
|
||||
@@ -27,6 +27,7 @@
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-next": "13.4.3",
|
||||
"isomorphic-unfetch": "^4.0.2",
|
||||
"mddb": "^0.1.9",
|
||||
"next": "13.4.3",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"papaparse": "^5.4.1",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@import "@flowershow/remark-callouts/styles.css";
|
||||
@import "@portaljs/remark-callouts/styles.css";
|
||||
|
||||
/* mathjax */
|
||||
.math-inline > mjx-container > svg {
|
||||
|
||||
1069
examples/fivethirtyeight/package-lock.json
generated
1069
examples/fivethirtyeight/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,11 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@flowershow/core": "^0.4.13",
|
||||
"@headlessui/react": "^1.7.14",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"@portaljs/components": "^0.1.8",
|
||||
"@portaljs/core": "^1.0.5",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@types/node": "20.1.1",
|
||||
"@types/react": "18.2.6",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import '@/styles/globals.css';
|
||||
import '@portaljs/components/styles.css';
|
||||
import { useEffect } from 'react';
|
||||
import { pageview } from '@flowershow/core';
|
||||
import { pageview } from '@portaljs/core';
|
||||
import Script from 'next/script';
|
||||
import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MDXRemote } from 'next-mdx-remote';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Mermaid } from '@flowershow/core';
|
||||
import { Mermaid } from '@portaljs/core';
|
||||
|
||||
// Custom components/renderers to pass to MDX.
|
||||
// Since the MDX files aren't loaded by webpack, they have no knowledge of how
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import matter from "gray-matter";
|
||||
import mdxmermaid from "mdx-mermaid";
|
||||
import { h } from "hastscript";
|
||||
import remarkCallouts from "@flowershow/remark-callouts";
|
||||
import remarkEmbed from "@flowershow/remark-embed";
|
||||
import remarkCallouts from "@portaljs/remark-callouts";
|
||||
import remarkEmbed from "@portaljs/remark-embed";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import remarkMath from "remark-math";
|
||||
import remarkSmartypants from "remark-smartypants";
|
||||
import remarkToc from "remark-toc";
|
||||
import remarkWikiLink from "@flowershow/remark-wiki-link";
|
||||
import remarkWikiLink from "@portaljs/remark-wiki-link";
|
||||
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
||||
import rehypeKatex from "rehype-katex";
|
||||
import rehypeSlug from "rehype-slug";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MarkdownDB } from "@flowershow/markdowndb";
|
||||
import { MarkdownDB } from "mddb";
|
||||
|
||||
const dbPath = "markdown.db";
|
||||
|
||||
|
||||
586
examples/github-backed-catalog/package-lock.json
generated
586
examples/github-backed-catalog/package-lock.json
generated
@@ -8,16 +8,17 @@
|
||||
"name": "my-app",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@flowershow/core": "^0.4.13",
|
||||
"@flowershow/markdowndb": "^0.1.5",
|
||||
"@flowershow/remark-callouts": "^1.0.0",
|
||||
"@flowershow/remark-embed": "^1.0.0",
|
||||
"@portaljs/components": "^0.1.6",
|
||||
"@portaljs/core": "^1.0.5",
|
||||
"@portaljs/remark-callouts": "^1.0.5",
|
||||
"@portaljs/remark-embed": "^1.0.4",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"@types/node": "18.16.0",
|
||||
"@types/react": "18.0.38",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"eslint": "8.39.0",
|
||||
"eslint-config-next": "13.3.1",
|
||||
"mddb": "^0.1.9",
|
||||
"next": "13.4.3",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"next-seo": "^6.0.0",
|
||||
@@ -45,19 +46,31 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/autocomplete-core": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.8.2.tgz",
|
||||
"integrity": "sha512-mTeshsyFhAqw/ebqNsQpMtbnjr+qVOSKXArEj4K0d7sqc8It1XD0gkASwecm9mF/jlOQ4Z9RNg1HbdA8JPdRwQ==",
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.2.tgz",
|
||||
"integrity": "sha512-hkG80c9kx9ClVAEcUJbTd2ziVC713x9Bji9Ty4XJfKXlxlsx3iXsoNhAwfeR4ulzIUg7OE5gez0UU1zVDdG7kg==",
|
||||
"dependencies": {
|
||||
"@algolia/autocomplete-shared": "1.8.2"
|
||||
"@algolia/autocomplete-plugin-algolia-insights": "1.9.2",
|
||||
"@algolia/autocomplete-shared": "1.9.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/autocomplete-plugin-algolia-insights": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.2.tgz",
|
||||
"integrity": "sha512-2LVsf4W66hVHQ3Ua/8k15oPlxjELCztbAkQm/hP42Sw+GLkHAdY1vaVRYziaWq64+Oljfg6FKkZHCdgXH+CGIA==",
|
||||
"dependencies": {
|
||||
"@algolia/autocomplete-shared": "1.9.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"search-insights": ">= 1 < 3"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/autocomplete-preset-algolia": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.8.2.tgz",
|
||||
"integrity": "sha512-J0oTx4me6ZM9kIKPuL3lyU3aB8DEvpVvR6xWmHVROx5rOYJGQcZsdG4ozxwcOyiiu3qxMkIbzntnV1S1VWD8yA==",
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.2.tgz",
|
||||
"integrity": "sha512-pqgIm2GNqtCT59Y1ICctIPrYTi34+wNPiNWEclD/yDzp5uDUUsyGe5XrUjCNyQRTKonAlmYxoaEHOn8FWgmBHA==",
|
||||
"dependencies": {
|
||||
"@algolia/autocomplete-shared": "1.8.2"
|
||||
"@algolia/autocomplete-shared": "1.9.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@algolia/client-search": ">= 4.9.1 < 6",
|
||||
@@ -65,123 +78,127 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/autocomplete-shared": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.8.2.tgz",
|
||||
"integrity": "sha512-b6Z/X4MczChMcfhk6kfRmBzPgjoPzuS9KGR4AFsiLulLNRAAqhP+xZTKtMnZGhLuc61I20d5WqlId02AZvcO6g=="
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.2.tgz",
|
||||
"integrity": "sha512-XxX6YDn+7LG+SmdpXEOnj7fc3TjiVpQ0CbGhjLwrd2tYr6LVY2D4Iiu/iuYJ4shvVDWWnpwArSk0uIWC/8OPUA==",
|
||||
"peerDependencies": {
|
||||
"@algolia/client-search": ">= 4.9.1 < 6",
|
||||
"algoliasearch": ">= 4.9.1 < 6"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/cache-browser-local-storage": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.1.tgz",
|
||||
"integrity": "sha512-e91Jpu93X3t3mVdQwF3ZDjSFMFIfzSc+I76G4EX8nl9RYXgqcjframoL05VTjcD2YCsI18RIHAWVCBoCXVZnrw==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.2.tgz",
|
||||
"integrity": "sha512-ZkVN7K/JE+qMQbpR6h3gQOGR6yCJpmucSBCmH5YDxnrYbp2CbrVCu0Nr+FGVoWzMJNznj1waShkfQ9awERulLw==",
|
||||
"dependencies": {
|
||||
"@algolia/cache-common": "4.17.1"
|
||||
"@algolia/cache-common": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/cache-common": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.1.tgz",
|
||||
"integrity": "sha512-fvi1WT8aSiGAKrcTw8Qg3RYgcwW8GZMHcqEm4AyDBEy72JZlFBSY80cTQ75MslINjCHXLDT+9EN8AGI9WVY7uA=="
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.2.tgz",
|
||||
"integrity": "sha512-fojbhYIS8ovfYs6hwZpy1O4mBfVRxNgAaZRqsdVQd54hU4MxYDYFCxagYX28lOBz7btcDHld6BMoWXvjzkx6iQ=="
|
||||
},
|
||||
"node_modules/@algolia/cache-in-memory": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.1.tgz",
|
||||
"integrity": "sha512-NbBt6eBWlsXc5geSpfPRC5dkIB/0Ptthw8r0yM5Z7D3sPlYdnTZSO9y9XWXIptRMwmZe4cM8iBMN8y0tzbcBkA==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.2.tgz",
|
||||
"integrity": "sha512-UYQcMzPurNi+cPYkuPemTZkjKAjdgAS1hagC5irujKbrYnN4yscK4TkOI5tX+O8/KegtJt3kOK07OIrJ2QDAAw==",
|
||||
"dependencies": {
|
||||
"@algolia/cache-common": "4.17.1"
|
||||
"@algolia/cache-common": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/client-account": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.1.tgz",
|
||||
"integrity": "sha512-3rL/6ofJvyL+q8TiWM3qoM9tig+SY4gB1Vbsj+UeJPnJm8Khm+7OS+r+mFraqR6pTehYqN8yGYoE7x4diEn4aA==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.2.tgz",
|
||||
"integrity": "sha512-doSk89pBPDpDyKJSHFADIGa2XSGrBCj3QwPvqtRJXDADpN+OjW+eTR8r4hEs/7X4GGfjfAOAES8JgDx+fZntYw==",
|
||||
"dependencies": {
|
||||
"@algolia/client-common": "4.17.1",
|
||||
"@algolia/client-search": "4.17.1",
|
||||
"@algolia/transporter": "4.17.1"
|
||||
"@algolia/client-common": "4.17.2",
|
||||
"@algolia/client-search": "4.17.2",
|
||||
"@algolia/transporter": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/client-analytics": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.1.tgz",
|
||||
"integrity": "sha512-Bepr2w249vODqeBtM7i++tPmUsQ9B81aupUGbDWmjA/FX+jzQqOdhW8w1CFO5kWViNKTbz2WBIJ9U3x8hOa4bA==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.2.tgz",
|
||||
"integrity": "sha512-V+DcXbOtD/hKwAR3qGQrtlrJ3q2f9OKfx843q744o4m3xHv5ueCAvGXB1znPsdaUrVDNAImcgEgqwI9x7EJbDw==",
|
||||
"dependencies": {
|
||||
"@algolia/client-common": "4.17.1",
|
||||
"@algolia/client-search": "4.17.1",
|
||||
"@algolia/requester-common": "4.17.1",
|
||||
"@algolia/transporter": "4.17.1"
|
||||
"@algolia/client-common": "4.17.2",
|
||||
"@algolia/client-search": "4.17.2",
|
||||
"@algolia/requester-common": "4.17.2",
|
||||
"@algolia/transporter": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/client-common": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.1.tgz",
|
||||
"integrity": "sha512-+r7kg4EgbFnGsDnoGSVNtXZO8xvZ0vzf1WAOV7sqV9PMf1bp6cpJP/3IuPrSk4t5w2KVl+pC8jfTM7HcFlfBEQ==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.2.tgz",
|
||||
"integrity": "sha512-gKBUnjxi0ukJYIJxVREYGt1Dmj1B3RBYbfGWi0dIPp1BC1VvQm+BOuNwsIwmq/x3MPO+sGuK978eKiP3tZDvag==",
|
||||
"dependencies": {
|
||||
"@algolia/requester-common": "4.17.1",
|
||||
"@algolia/transporter": "4.17.1"
|
||||
"@algolia/requester-common": "4.17.2",
|
||||
"@algolia/transporter": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/client-personalization": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.1.tgz",
|
||||
"integrity": "sha512-gJku9DG/THJpfsSlG/az0a3QIn+VVff9kKh8PG8+7ZfxOHS+C+Y5YSeZVsC+c2cfoKLPo3CuHIiJ/p86erR3bA==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.2.tgz",
|
||||
"integrity": "sha512-wc4UgOWxSYWz5wpuelNmlt895jA9twjZWM2ms17Ws8qCvBHF7OVGdMGgbysPB8790YnfvvDnSsWOv3CEj26Eow==",
|
||||
"dependencies": {
|
||||
"@algolia/client-common": "4.17.1",
|
||||
"@algolia/requester-common": "4.17.1",
|
||||
"@algolia/transporter": "4.17.1"
|
||||
"@algolia/client-common": "4.17.2",
|
||||
"@algolia/requester-common": "4.17.2",
|
||||
"@algolia/transporter": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/client-search": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.1.tgz",
|
||||
"integrity": "sha512-Q5YfT5gVkx60PZDQBqp/zH9aUbBdC7HVvxupiHUgnCKqRQsRZjOhLest7AI6FahepuZLBZS62COrO7v+JvKY7w==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.2.tgz",
|
||||
"integrity": "sha512-FUjIs+gRe0upJC++uVs4sdxMw15JxfkT86Gr/kqVwi9kcqaZhXntSbW/Fw959bIYXczjmeVQsilYvBWW4YvSZA==",
|
||||
"dependencies": {
|
||||
"@algolia/client-common": "4.17.1",
|
||||
"@algolia/requester-common": "4.17.1",
|
||||
"@algolia/transporter": "4.17.1"
|
||||
"@algolia/client-common": "4.17.2",
|
||||
"@algolia/requester-common": "4.17.2",
|
||||
"@algolia/transporter": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/logger-common": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.1.tgz",
|
||||
"integrity": "sha512-Us28Ot+fLEmX9M96sa65VZ8EyEEzhYPxfhV9aQyKDjfXbUdJlJxKt6wZpoEg9RAPSdO8IjK9nmuW2P8au3rRsg=="
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.2.tgz",
|
||||
"integrity": "sha512-EfXuweUE+1HiSMsQidaDWA5Lv4NnStYIlh7PO5pLkI+sdhbMX0e5AO5nUAMIFM1VkEANes70RA8fzhP6OqCqQQ=="
|
||||
},
|
||||
"node_modules/@algolia/logger-console": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.1.tgz",
|
||||
"integrity": "sha512-iKGQTpOjHiE64W3JIOu6dmDvn+AfYIElI9jf/Nt6umRPmP/JI9rK+OHUoW4pKrBtdG0DPd62ppeNXzSnLxY6/g==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.2.tgz",
|
||||
"integrity": "sha512-JuG8HGVlJ+l/UEDK4h2Y8q/IEmRjQz1J0aS9tf6GPNbGYiSvMr1DDdZ+hqV3bb1XE6wU8Ypex56HisWMSpnG0A==",
|
||||
"dependencies": {
|
||||
"@algolia/logger-common": "4.17.1"
|
||||
"@algolia/logger-common": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/requester-browser-xhr": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.1.tgz",
|
||||
"integrity": "sha512-W5mGfGDsyfVR+r4pUFrYLGBEM18gs38+GNt5PE5uPULy4uVTSnnVSkJkWeRkmLBk9zEZ/Nld8m4zavK6dtEuYg==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.2.tgz",
|
||||
"integrity": "sha512-FKI2lYWwksALfRt2OETFmGb5+P7WVc4py2Ai3H7k8FSfTLwVvs9WVVmtlx6oANQ8RFEK4B85h8DQJTJ29TDfmA==",
|
||||
"dependencies": {
|
||||
"@algolia/requester-common": "4.17.1"
|
||||
"@algolia/requester-common": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/requester-common": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.1.tgz",
|
||||
"integrity": "sha512-HggXdjvVFQR0I5l7hM5WdHgQ1tqcRWeyXZz8apQ7zPWZhirmY2E9D6LVhDh/UnWQNEm7nBtM+eMFONJ3bZccIQ=="
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.2.tgz",
|
||||
"integrity": "sha512-Rfim23ztAhYpE9qm+KCfCRo+YLJCjiiTG+IpDdzUjMpYPhUtirQT0A35YEd/gKn86YNyydxS9w8iRSjwKh+L0A=="
|
||||
},
|
||||
"node_modules/@algolia/requester-node-http": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.1.tgz",
|
||||
"integrity": "sha512-NzFWecXT6d0PPsQY9L+/qoK2deF74OLcpvqCH+Vh3mh+QzPsFafcBExdguAjZsAWDn1R6JEeFW7/fo/p0SE57w==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.2.tgz",
|
||||
"integrity": "sha512-E0b0kyCDMvUIhQmDNd/mH4fsKJdEEX6PkMKrYJjzm6moo+rP22tqpq4Rfe7DZD8OB6/LsDD3zs3Kvd+L+M5wwQ==",
|
||||
"dependencies": {
|
||||
"@algolia/requester-common": "4.17.1"
|
||||
"@algolia/requester-common": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/transporter": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.1.tgz",
|
||||
"integrity": "sha512-ZM+qhX47Vh46mWH8/U9ihvy98HdTYpYQDSlqBD7IbiUbbyoCMke+qmdSX2MGhR2FCcXBSxejsJKKVAfbpaLVgg==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.2.tgz",
|
||||
"integrity": "sha512-m8pXlz5OnNzjD1rcw+duCN4jG4yEzkJBsvKYMoN22Oq6rQwy1AY5muZ+IQUs4dL+A364CYkRMLRWhvXpCZ1x+g==",
|
||||
"dependencies": {
|
||||
"@algolia/cache-common": "4.17.1",
|
||||
"@algolia/logger-common": "4.17.1",
|
||||
"@algolia/requester-common": "4.17.1"
|
||||
"@algolia/cache-common": "4.17.2",
|
||||
"@algolia/logger-common": "4.17.2",
|
||||
"@algolia/requester-common": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@@ -353,18 +370,18 @@
|
||||
"integrity": "sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg=="
|
||||
},
|
||||
"node_modules/@docsearch/css": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.4.0.tgz",
|
||||
"integrity": "sha512-Hg8Xfma+rFwRi6Y/pfei4FJoQ1hdVURmmNs/XPoMTCPAImU+d5yxj+M+qdLtNjWRpfWziU4dQcqY94xgFBn2dg=="
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.0.tgz",
|
||||
"integrity": "sha512-Ob5FQLubplcBNihAVtriR59FRBeP8u69F6mu4L4yIr60KfsPc10bOV0DoPErJw0zF9IBN2cNLW9qdmt8zWPxyg=="
|
||||
},
|
||||
"node_modules/@docsearch/react": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.4.0.tgz",
|
||||
"integrity": "sha512-ufrp5879XYGojgS30ZAp8H4qIMbahRHB9M85VDBP36Xgz5QjYM54i1URKj5e219F7gqTtOivfztFTij6itc0MQ==",
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.0.tgz",
|
||||
"integrity": "sha512-3IG8mmSMzSHNGy2S1VuPyYU9tFCxFpj5Ov8SYwsSHM4yMvFsaO9oFxXocA5lSenliIELhuOuS5+BdxHa/Qlf2A==",
|
||||
"dependencies": {
|
||||
"@algolia/autocomplete-core": "1.8.2",
|
||||
"@algolia/autocomplete-preset-algolia": "1.8.2",
|
||||
"@docsearch/css": "3.4.0",
|
||||
"@algolia/autocomplete-core": "1.9.2",
|
||||
"@algolia/autocomplete-preset-algolia": "1.9.2",
|
||||
"@docsearch/css": "3.5.0",
|
||||
"algoliasearch": "^4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -573,16 +590,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.6.tgz",
|
||||
"integrity": "sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg=="
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.3.0.tgz",
|
||||
"integrity": "sha512-vX1WVAdPjZg9DkDkC+zEx/tKtnST6/qcNpwcjeBgco3XRNHz5PUA+ivi/yr6G3o0kMR60uKBJcfOdfzOFI7PMQ=="
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.8.tgz",
|
||||
"integrity": "sha512-XLwhYV90MxiHDq6S0rzFZj00fnDM+A1R9jhSioZoMsa7G0Q0i+Q4x40ajR8FHSdYDE1bgjG45mIWe6jtv9UPmg==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.3.0.tgz",
|
||||
"integrity": "sha512-qIAwejE3r6NeA107u4ELDKkH8+VtgRKdXqtSPaKflL2S2V+doyN+Wt9s5oHKXPDo4E8TaVXaHT3+6BbagH31xw==",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.2.6"
|
||||
"@floating-ui/core": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/react-dom": {
|
||||
@@ -612,103 +629,6 @@
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@flowershow/core": {
|
||||
"version": "0.4.13",
|
||||
"resolved": "https://registry.npmjs.org/@flowershow/core/-/core-0.4.13.tgz",
|
||||
"integrity": "sha512-UeDb70pjUGgILUXGQKFkytKL9ilwsTIM3jYsNNi55PKHXAaHEQA480Y+m2yNPgC5SzFlGj0FIP/zhH0JfBdNiw==",
|
||||
"dependencies": {
|
||||
"@docsearch/react": "^3.3.3",
|
||||
"@floating-ui/react-dom": "^1.3.0",
|
||||
"@floating-ui/react-dom-interactions": "^0.13.3",
|
||||
"@giscus/react": "^2.2.6",
|
||||
"@headlessui/react": "^1.7.12",
|
||||
"clsx": "^1.2.1",
|
||||
"disqus-react": "^1.1.5",
|
||||
"framer-motion": "^10.0.1",
|
||||
"kbar": "0.1.0-beta.40",
|
||||
"mdx-mermaid": "2.0.0-rc7",
|
||||
"mermaid": "10.0.1-rc.2",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": "^13.2.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@flowershow/core/node_modules/dagre-d3-es": {
|
||||
"version": "7.0.8",
|
||||
"resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.8.tgz",
|
||||
"integrity": "sha512-eykdoYQ4FwCJinEYS0gPL2f2w+BPbSLvnQSJ3Ye1vAoPjdkq6xIMKBv+UkICd3qZE26wBKIn3p+6n0QC7R1LyA==",
|
||||
"dependencies": {
|
||||
"d3": "^7.8.2",
|
||||
"lodash-es": "^4.17.21"
|
||||
}
|
||||
},
|
||||
"node_modules/@flowershow/core/node_modules/dompurify": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz",
|
||||
"integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ=="
|
||||
},
|
||||
"node_modules/@flowershow/core/node_modules/mermaid": {
|
||||
"version": "10.0.1-rc.2",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.0.1-rc.2.tgz",
|
||||
"integrity": "sha512-THnhraO9F6pQZY9Nv91QuWv35QdmZy/UW2FpadRN/1cLuqCyihNKIEOxuVLEPrgtFawt2nL+BpUoJKC4div3UQ==",
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.0",
|
||||
"cytoscape": "^3.23.0",
|
||||
"cytoscape-cose-bilkent": "^4.1.0",
|
||||
"cytoscape-fcose": "^2.1.0",
|
||||
"d3": "^7.4.0",
|
||||
"dagre-d3-es": "7.0.8",
|
||||
"dompurify": "2.4.3",
|
||||
"elkjs": "^0.8.2",
|
||||
"khroma": "^2.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"moment-mini": "^2.29.4",
|
||||
"non-layered-tidy-tree-layout": "^2.0.2",
|
||||
"stylis": "^4.1.2",
|
||||
"ts-dedent": "^2.2.0",
|
||||
"uuid": "^9.0.0",
|
||||
"web-worker": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@flowershow/markdowndb": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@flowershow/markdowndb/-/markdowndb-0.1.5.tgz",
|
||||
"integrity": "sha512-AfmkvgitNb7z150bTcCn/1lqwUhPRD3IhCbIwYxE5IXtL57+WwewJUNOU3SOKXNWg6eDVlfEq0H2GICSLAC4bw==",
|
||||
"dependencies": {
|
||||
"@flowershow/remark-wiki-link": "^1.1.2",
|
||||
"gray-matter": "^4.0.3",
|
||||
"knex": "^2.4.2",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-parse": "^10.0.1",
|
||||
"sqlite3": "^5.1.6",
|
||||
"unist-util-select": "^4.0.3"
|
||||
},
|
||||
"bin": {
|
||||
"mddb": "src/bin/index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@flowershow/remark-callouts": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@flowershow/remark-callouts/-/remark-callouts-1.0.0.tgz",
|
||||
"integrity": "sha512-zzHDpw1bswTTf+cbhNh2Bogf4ghpIcxAypFxYZxZ/afeGdN3NNSQwnamL8StY9uu6aQ/miq4Egbuof3xk2ksWA==",
|
||||
"dependencies": {
|
||||
"mdast-util-from-markdown": "^1.2.0",
|
||||
"svg-parser": "^2.0.4",
|
||||
"unist-util-visit": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@flowershow/remark-embed": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@flowershow/remark-embed/-/remark-embed-1.0.0.tgz",
|
||||
"integrity": "sha512-tADovIrhbmNWJj72C+pgT921+BuApmO6xxKU3HlWciRHkD6S4KqsikLjsopalK+VJmqluoHhhST0kf0S6xUKIA==",
|
||||
"dependencies": {
|
||||
"unist-util-visit": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@flowershow/remark-wiki-link": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@flowershow/remark-wiki-link/-/remark-wiki-link-1.2.0.tgz",
|
||||
@@ -1701,9 +1621,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@headlessui/react": {
|
||||
"version": "1.7.14",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.14.tgz",
|
||||
"integrity": "sha512-znzdq9PG8rkwcu9oQ2FwIy0ZFtP9Z7ycS+BAqJ3R5EIqC/0bJGvhT7193rFf+45i9nnPsYvCQVW4V/bB9Xc+gA==",
|
||||
"version": "1.7.15",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.15.tgz",
|
||||
"integrity": "sha512-OTO0XtoRQ6JPB1cKNFYBZv2Q0JMqMGNhYP1CjPvcJvjz8YGokz8oAj89HIYZGN0gZzn/4kk9iUpmMF4Q21Gsqw==",
|
||||
"dependencies": {
|
||||
"client-only": "^0.0.1"
|
||||
},
|
||||
@@ -1807,9 +1727,9 @@
|
||||
"integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
|
||||
},
|
||||
"node_modules/@lit/reactive-element": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.1.tgz",
|
||||
"integrity": "sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==",
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz",
|
||||
"integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==",
|
||||
"dependencies": {
|
||||
"@lit-labs/ssr-dom-shim": "^1.0.0"
|
||||
}
|
||||
@@ -2444,6 +2364,60 @@
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@portaljs/core": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@portaljs/core/-/core-1.0.5.tgz",
|
||||
"integrity": "sha512-HJ3eYjyKL7wrPlBwcEHzNd/SW2PwLu49nAsRTz8r7tgyRINDVkHTLVjZ5V6jCSYtuX7LSlxk0WMIZ9aDOocXDA==",
|
||||
"dependencies": {
|
||||
"@docsearch/react": "^3.3.3",
|
||||
"@floating-ui/react-dom": "^1.3.0",
|
||||
"@floating-ui/react-dom-interactions": "^0.13.3",
|
||||
"@giscus/react": "^2.2.6",
|
||||
"@headlessui/react": "^1.7.12",
|
||||
"clsx": "^1.2.1",
|
||||
"core-js": "^3.30.2",
|
||||
"disqus-react": "^1.1.5",
|
||||
"framer-motion": "^10.0.1",
|
||||
"kbar": "0.1.0-beta.40",
|
||||
"mermaid": "^10.2.2",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mdx-mermaid": "2.0.0-rc7",
|
||||
"next": "^13.2.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@portaljs/remark-callouts": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@portaljs/remark-callouts/-/remark-callouts-1.0.5.tgz",
|
||||
"integrity": "sha512-KMjr44isEvQzpNBBCP3s5/3TCmI/ce4xRvbOk6h9xicVZqE6BPTH9rhfOGvop9cchyAWgj9gmJXhQk+Bd+t5bg==",
|
||||
"dependencies": {
|
||||
"mdast-util-from-markdown": "^1.2.0",
|
||||
"svg-parser": "^2.0.4",
|
||||
"unist-util-visit": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@portaljs/remark-embed": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@portaljs/remark-embed/-/remark-embed-1.0.4.tgz",
|
||||
"integrity": "sha512-BvRMC1iBd5M93u9WS0mvunHoBMWgQQTCR7RdqSS9sRav5pqquiNG7il12Yza4vFpFBXwLkzEG0NwIVXzzutT8w==",
|
||||
"dependencies": {
|
||||
"unist-util-visit": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@portaljs/remark-wiki-link": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@portaljs/remark-wiki-link/-/remark-wiki-link-1.0.4.tgz",
|
||||
"integrity": "sha512-cp6vlssDAPawcBI0vUPRpcPdORql3RbK1Q+t1LuRvMQ+yiRb+9DnSPBUviDXKqwsBMOOXP/ePAdYohaeXGt0lQ==",
|
||||
"dependencies": {
|
||||
"mdast-util-to-markdown": "^1.5.0",
|
||||
"mdast-util-wiki-link": "^0.0.2",
|
||||
"micromark-util-symbol": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@primer/octicons-react": {
|
||||
"version": "12.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@primer/octicons-react/-/octicons-react-12.1.0.tgz",
|
||||
@@ -2474,27 +2448,43 @@
|
||||
"integrity": "sha512-Z8R0kdAZui8eYTuGY5oQUA0SU4jYq43m4bZW6Dw0B35fUp+U3r+pCrkj0EADJAPv1UaKNskSv/lrfRdC7719Rg=="
|
||||
},
|
||||
"node_modules/@radix-ui/react-compose-refs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz",
|
||||
"integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
|
||||
"integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-portal": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.2.tgz",
|
||||
"integrity": "sha512-swu32idoCW7KA2VEiUZGBSu9nB6qwGdV6k6HYhUoOo3M1FFpD+VgLzUqtt3mwL1ssz7r2x8MggpLSQach2Xy/Q==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.3.tgz",
|
||||
"integrity": "sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/react-primitive": "1.0.2"
|
||||
"@radix-ui/react-primitive": "1.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-presence": {
|
||||
@@ -2517,28 +2507,44 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-primitive": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz",
|
||||
"integrity": "sha512-zY6G5Qq4R8diFPNwtyoLRZBxzu1Z+SXMlfYpChN7Dv8gvmx9X3qhDqiLWvKseKVJMuedFeU/Sa0Sy/Ia+t06Dw==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz",
|
||||
"integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/react-slot": "1.0.1"
|
||||
"@radix-ui/react-slot": "1.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz",
|
||||
"integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
|
||||
"integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/react-compose-refs": "1.0.0"
|
||||
"@radix-ui/react-compose-refs": "1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/rect": {
|
||||
@@ -2862,6 +2868,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
|
||||
"integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@@ -3078,24 +3085,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/algoliasearch": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.1.tgz",
|
||||
"integrity": "sha512-4GDQ1RhP2qUR3x8PevFRbEdqZqIARNViZYjgTJmA1T7wRNtFA3W4Aqc/RsODqa1J8IO/QDla5x4tWuUS8NV8wA==",
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.2.tgz",
|
||||
"integrity": "sha512-VFu43JJNYIW74awp7oeQcQsPcxOhd8psqBDTfyNO2Zt6L1NqnNMTVnaIdQ+8dtKqUDBqQZp0szPxECvX8CK2Fg==",
|
||||
"dependencies": {
|
||||
"@algolia/cache-browser-local-storage": "4.17.1",
|
||||
"@algolia/cache-common": "4.17.1",
|
||||
"@algolia/cache-in-memory": "4.17.1",
|
||||
"@algolia/client-account": "4.17.1",
|
||||
"@algolia/client-analytics": "4.17.1",
|
||||
"@algolia/client-common": "4.17.1",
|
||||
"@algolia/client-personalization": "4.17.1",
|
||||
"@algolia/client-search": "4.17.1",
|
||||
"@algolia/logger-common": "4.17.1",
|
||||
"@algolia/logger-console": "4.17.1",
|
||||
"@algolia/requester-browser-xhr": "4.17.1",
|
||||
"@algolia/requester-common": "4.17.1",
|
||||
"@algolia/requester-node-http": "4.17.1",
|
||||
"@algolia/transporter": "4.17.1"
|
||||
"@algolia/cache-browser-local-storage": "4.17.2",
|
||||
"@algolia/cache-common": "4.17.2",
|
||||
"@algolia/cache-in-memory": "4.17.2",
|
||||
"@algolia/client-account": "4.17.2",
|
||||
"@algolia/client-analytics": "4.17.2",
|
||||
"@algolia/client-common": "4.17.2",
|
||||
"@algolia/client-personalization": "4.17.2",
|
||||
"@algolia/client-search": "4.17.2",
|
||||
"@algolia/logger-common": "4.17.2",
|
||||
"@algolia/logger-console": "4.17.2",
|
||||
"@algolia/requester-browser-xhr": "4.17.2",
|
||||
"@algolia/requester-common": "4.17.2",
|
||||
"@algolia/requester-node-http": "4.17.2",
|
||||
"@algolia/transporter": "4.17.2"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
@@ -3402,7 +3409,8 @@
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.3",
|
||||
@@ -3430,6 +3438,7 @@
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
@@ -3532,6 +3541,7 @@
|
||||
}
|
||||
],
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
@@ -3542,6 +3552,7 @@
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
@@ -3905,6 +3916,16 @@
|
||||
"toggle-selection": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "3.31.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.0.tgz",
|
||||
"integrity": "sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ==",
|
||||
"hasInstallScript": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"node_modules/cose-base": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz",
|
||||
@@ -3933,6 +3954,7 @@
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
||||
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"node-fetch": "2.6.7"
|
||||
}
|
||||
@@ -3942,6 +3964,7 @@
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
@@ -4080,9 +4103,9 @@
|
||||
"integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="
|
||||
},
|
||||
"node_modules/d3": {
|
||||
"version": "7.8.4",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz",
|
||||
"integrity": "sha512-q2WHStdhiBtD8DMmhDPyJmXUxr6VWRngKyiJ5EfXMxPw+tqT6BhNjhJZ4w3BHsNm3QoVfZLY8Orq/qPFczwKRA==",
|
||||
"version": "7.8.5",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
|
||||
"integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
|
||||
"dependencies": {
|
||||
"d3-array": "3",
|
||||
"d3-axis": "3",
|
||||
@@ -4489,7 +4512,6 @@
|
||||
"version": "7.0.10",
|
||||
"resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz",
|
||||
"integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"d3": "^7.8.2",
|
||||
"lodash-es": "^4.17.21"
|
||||
@@ -4516,10 +4538,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.7",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
|
||||
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==",
|
||||
"peer": true
|
||||
"version": "1.11.8",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.8.tgz",
|
||||
"integrity": "sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
@@ -4685,7 +4706,8 @@
|
||||
"version": "0.0.1045489",
|
||||
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1045489.tgz",
|
||||
"integrity": "sha512-D+PTmWulkuQW4D1NTiCRCFxF7pQPn0hgp4YyX4wAQ6xYXKOadSWPR3ENGDQ47MW/Ewc9v2rpC/UEEGahgBYpSQ==",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/didyoumean": {
|
||||
"version": "1.2.2",
|
||||
@@ -4739,8 +4761,7 @@
|
||||
"node_modules/dompurify": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.3.tgz",
|
||||
"integrity": "sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ==",
|
||||
"peer": true
|
||||
"integrity": "sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ=="
|
||||
},
|
||||
"node_modules/downshift": {
|
||||
"version": "6.1.12",
|
||||
@@ -4807,6 +4828,7 @@
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
@@ -5521,6 +5543,7 @@
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
|
||||
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"get-stream": "^5.1.0",
|
||||
@@ -5615,6 +5638,7 @@
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"pend": "~1.2.0"
|
||||
}
|
||||
@@ -5749,7 +5773,8 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
@@ -5884,6 +5909,7 @@
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
@@ -6456,7 +6482,8 @@
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.2.4",
|
||||
@@ -7350,9 +7377,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lit": {
|
||||
"version": "2.7.4",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.7.4.tgz",
|
||||
"integrity": "sha512-cgD7xrZoYr21mbrkZIuIrj98YTMw/snJPg52deWVV4A8icLyNHI3bF70xsJeAgwTuiq5Kkd+ZR8gybSJDCPB7g==",
|
||||
"version": "2.7.5",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-2.7.5.tgz",
|
||||
"integrity": "sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^1.6.0",
|
||||
"lit-element": "^3.3.0",
|
||||
@@ -7993,6 +8020,23 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/mddb": {
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/mddb/-/mddb-0.1.9.tgz",
|
||||
"integrity": "sha512-d3B5zArnWDqKN1Blq6hGtfr3HTHUKK/GS95b4OZqcyDPvUP4JnYuWHDjyoJ0tSgDKH6ybB6WdnnI3tcHQvRTyw==",
|
||||
"dependencies": {
|
||||
"@flowershow/remark-wiki-link": "^1.1.2",
|
||||
"gray-matter": "^4.0.3",
|
||||
"knex": "^2.4.2",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-parse": "^10.0.1",
|
||||
"sqlite3": "^5.1.6",
|
||||
"unist-util-select": "^4.0.3"
|
||||
},
|
||||
"bin": {
|
||||
"mddb": "dist/src/bin/index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/mdn-data": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
|
||||
@@ -8002,6 +8046,7 @@
|
||||
"version": "2.0.0-rc7",
|
||||
"resolved": "https://registry.npmjs.org/mdx-mermaid/-/mdx-mermaid-2.0.0-rc7.tgz",
|
||||
"integrity": "sha512-AMy3138EsvcGwE4cGqUVytj4mLpJ3TJ2nek82+67Qi4GSOXoelAqmQudHSk26IsP091c3qX4d/4wi9CqLwFl9Q==",
|
||||
"peer": true,
|
||||
"optionalDependencies": {
|
||||
"estree-util-to-js": "^1.1.0",
|
||||
"estree-util-visit": "^1.2.0",
|
||||
@@ -8032,10 +8077,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mermaid": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.2.0.tgz",
|
||||
"integrity": "sha512-mYKXlH9ngKdMsJ87VYMdlDZXS+MXDAGKPf3XzDf2vvAPnmRoFm7GFebemOAOWYI1bWSECDyoWTGwesWe6mW1Cw==",
|
||||
"peer": true,
|
||||
"version": "10.2.3",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.2.3.tgz",
|
||||
"integrity": "sha512-cMVE5s9PlQvOwfORkyVpr5beMsLdInrycAosdr+tpZ0WFjG4RJ/bUHST7aTgHNJbujHkdBRAm+N50P3puQOfPw==",
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.2",
|
||||
"cytoscape": "^3.23.0",
|
||||
@@ -8899,7 +8943,8 @@
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/modern-normalize": {
|
||||
"version": "1.1.0",
|
||||
@@ -8912,11 +8957,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/moment-mini": {
|
||||
"version": "2.29.4",
|
||||
"resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.29.4.tgz",
|
||||
"integrity": "sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg=="
|
||||
},
|
||||
"node_modules/mri": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
||||
@@ -9641,7 +9681,8 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/periscopic": {
|
||||
"version": "3.1.0",
|
||||
@@ -9850,6 +9891,7 @@
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
@@ -9896,13 +9938,15 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
@@ -9923,6 +9967,7 @@
|
||||
"deprecated": "< 19.4.0 is no longer supported",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"progress": "2.0.3",
|
||||
@@ -9938,6 +9983,7 @@
|
||||
"resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-18.2.1.tgz",
|
||||
"integrity": "sha512-MRtTAZfQTluz3U2oU/X2VqVWPcR1+94nbA2V6ZrSZRVEwLqZ8eclZ551qGFQD/vD2PYqHJwWOW/fpC721uznVw==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cross-fetch": "3.1.5",
|
||||
"debug": "4.3.4",
|
||||
@@ -10804,6 +10850,15 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/search-insights": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.6.0.tgz",
|
||||
"integrity": "sha512-vU2/fJ+h/Mkm/DJOe+EaM5cafJv/1rRTZpGJTuFPf/Q5LjzgMDsqPdSaZsAe+GAWHHsfsu+rQSAn6c8IGtBEVw==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/section-matter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||
@@ -11403,6 +11458,7 @@
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
|
||||
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
@@ -11414,13 +11470,15 @@
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/tar-stream": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
@@ -11484,7 +11542,8 @@
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/tildify": {
|
||||
"version": "2.0.0",
|
||||
@@ -11867,6 +11926,7 @@
|
||||
"resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
|
||||
"integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"buffer": "^5.2.1",
|
||||
"through": "^2.3.8"
|
||||
@@ -12880,6 +12940,7 @@
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz",
|
||||
"integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
@@ -12955,6 +13016,7 @@
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
||||
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"buffer-crc32": "~0.2.3",
|
||||
"fd-slicer": "~1.1.0"
|
||||
|
||||
@@ -10,16 +10,17 @@
|
||||
"prettier": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@flowershow/core": "^0.4.13",
|
||||
"@flowershow/markdowndb": "^0.1.5",
|
||||
"@flowershow/remark-callouts": "^1.0.0",
|
||||
"@flowershow/remark-embed": "^1.0.0",
|
||||
"@portaljs/components": "^0.1.6",
|
||||
"@portaljs/core": "^1.0.5",
|
||||
"@portaljs/remark-callouts": "^1.0.5",
|
||||
"@portaljs/remark-embed": "^1.0.4",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"@types/node": "18.16.0",
|
||||
"@types/react": "18.0.38",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"eslint": "8.39.0",
|
||||
"eslint-config-next": "13.3.1",
|
||||
"mddb": "^0.1.9",
|
||||
"next": "13.4.3",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"next-seo": "^6.0.0",
|
||||
|
||||
@@ -79,7 +79,7 @@ pre {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@import "@flowershow/remark-callouts/styles.css";
|
||||
@import "@portaljs/remark-callouts/styles.css";
|
||||
|
||||
/* mathjax */
|
||||
.math-inline > mjx-container > svg {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MDXRemote } from 'next-mdx-remote';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Mermaid } from '@flowershow/core';
|
||||
import { Mermaid } from '@portaljs/core';
|
||||
|
||||
// Custom components/renderers to pass to MDX.
|
||||
// Since the MDX files aren't loaded by webpack, they have no knowledge of how
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import matter from "gray-matter";
|
||||
import mdxmermaid from "mdx-mermaid";
|
||||
import { h } from "hastscript";
|
||||
import remarkCallouts from "@flowershow/remark-callouts";
|
||||
import remarkEmbed from "@flowershow/remark-embed";
|
||||
import remarkCallouts from "@portaljs/remark-callouts";
|
||||
import remarkEmbed from "@portaljs/remark-embed";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import remarkMath from "remark-math";
|
||||
import remarkSmartypants from "remark-smartypants";
|
||||
import remarkToc from "remark-toc";
|
||||
import remarkWikiLink from "@flowershow/remark-wiki-link";
|
||||
import remarkWikiLink from "@portaljs/remark-wiki-link";
|
||||
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
||||
import rehypeKatex from "rehype-katex";
|
||||
import rehypeSlug from "rehype-slug";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MarkdownDB } from "@flowershow/markdowndb";
|
||||
import { MarkdownDB } from "mddb";
|
||||
|
||||
const dbPath = "markdown.db";
|
||||
|
||||
|
||||
1969
examples/learn/package-lock.json
generated
1969
examples/learn/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,17 +12,28 @@
|
||||
"mddb": "mddb ./content"
|
||||
},
|
||||
"dependencies": {
|
||||
"@flowershow/core": "^0.4.10",
|
||||
"@flowershow/markdowndb": "^0.1.1",
|
||||
"@flowershow/remark-callouts": "^1.0.0",
|
||||
"@flowershow/remark-embed": "^1.0.0",
|
||||
"@flowershow/remark-wiki-link": "^1.1.2",
|
||||
"@githubocto/flat-ui": "^0.14.1",
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@opentelemetry/api": "^1.4.0",
|
||||
"@portaljs/components": "^0.1.8",
|
||||
"@portaljs/core": "^1.0.5",
|
||||
"@portaljs/remark-callouts": "^1.0.5",
|
||||
"@portaljs/remark-embed": "^1.0.4",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"@tanstack/react-table": "^8.8.5",
|
||||
"flexsearch": "0.7.21",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hastscript": "^7.2.0",
|
||||
"mddb": "^0.1.9",
|
||||
"mdx-mermaid": "2.0.0-rc7",
|
||||
"next": "13.2.1",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"papaparse": "^5.4.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.43.9",
|
||||
"react-query": "^3.39.3",
|
||||
"react-vega": "^7.6.0",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"rehype-katex": "^6.0.3",
|
||||
"rehype-prism-plus": "^1.5.1",
|
||||
@@ -32,17 +43,6 @@
|
||||
"remark-smartypants": "^2.0.0",
|
||||
"remark-toc": "^8.0.1",
|
||||
"typescript": "5.0.4",
|
||||
"@githubocto/flat-ui": "^0.14.1",
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@tanstack/react-table": "^8.8.5",
|
||||
"flexsearch": "0.7.21",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"papaparse": "^5.4.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.43.9",
|
||||
"react-query": "^3.39.3",
|
||||
"react-vega": "^7.6.0",
|
||||
"vega": "5.25.0",
|
||||
"vega-lite": "5.1.0"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import "@flowershow/remark-callouts/styles.css";
|
||||
@import "@portaljs/remark-callouts/styles.css";
|
||||
|
||||
.w-5 {
|
||||
width: 1.25rem
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MDXRemote } from 'next-mdx-remote';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Mermaid } from '@flowershow/core';
|
||||
import { Mermaid } from '@portaljs/core';
|
||||
|
||||
// Custom components/renderers to pass to MDX.
|
||||
// Since the MDX files aren't loaded by webpack, they have no knowledge of how
|
||||
|
||||
@@ -53,6 +53,10 @@ export function Header() {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Contributing',
|
||||
href: '/contributing',
|
||||
},
|
||||
{
|
||||
title: 'Resources',
|
||||
href: '/resources',
|
||||
|
||||
38
examples/openspending/content/contributing.md
Normal file
38
examples/openspending/content/contributing.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# How to contribute
|
||||
|
||||
OpenSpending is a project that aims to make public financial data more accessible, understandable, and usable. It is powered by PortalJS, a framework for building data portals that are fast, secure, and easy to customize.
|
||||
|
||||
If you have any questions, the best place to get answers is to reach to us on [Discord](https://discord.gg/xJrxCbkP)
|
||||
|
||||
We welcome contributions from anyone who is interested in improving OpenSpending and making it more useful for the public. There are many ways you can contribute to the project, such as:
|
||||
|
||||
- Submitting datasets for evaluation and inclusion in OpenSpending
|
||||
- Reporting bugs or issues with the website or the data
|
||||
- Suggesting new features or enhancements
|
||||
- Providing feedback or ideas
|
||||
- Helping other users or answering questions
|
||||
|
||||
## Submitting a contribution
|
||||
|
||||
The main platform for communication and collaboration for OpenSpending is Github, if you want to interact with us you can o so by submitting an issue.
|
||||
|
||||
**Repo for issues:** [https://github.com/os-data/registry/issues](https://github.com/os-data/registry/issues)
|
||||
|
||||
If you want to submit a dataset for evaluation and inclusion in OpenSpending, you will need to create an issue on Github using this template:
|
||||
|
||||
```markdown
|
||||
Title: [Dataset Submission] Name of the dataset (This will be the name of the repo where your datasets will be stored)
|
||||
Readme: A description of your data to include in the new repo that will be created
|
||||
Datapackage: All our datasets require a datapackage following the [frictionless spec](https://specs.frictionlessdata.io/) more specific the [fiscal version](https://specs.frictionlessdata.io/fiscal-data-package/)
|
||||
```
|
||||
|
||||
Please make sure that the dataset meets the following criteria before submitting it:
|
||||
|
||||
- The dataset contains public financial data (e.g., budgets, expenditures, revenues, contracts)
|
||||
- The dataset is open and free to use (e.g., no restrictions on access or reuse)
|
||||
- The dataset is structured and machine-readable (e.g., no scanned images or PDFs)
|
||||
- The dataset has a datapackage containing metadata and documentation (e.g., descriptions, definitions, schemas)
|
||||
|
||||
If you have any questions or doubts about submitting a dataset, please contact us on Github or join our [Discord server](https://discord.gg/xJrxCbkP), where you can chat with other contributors and get support from the OpenSpending team.
|
||||
|
||||
We appreciate your interest and involvement in OpenSpending, and we look forward to working with you on making public financial data more open and transparent. Thank you for your contribution! 😊
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
title: Sample Data Story
|
||||
date: 06/06/2023
|
||||
---
|
||||
|
||||
This is a sample data story, you can add charts
|
||||
|
||||
<LineChart
|
||||
data="https://raw.githubusercontent.com/datasets/oil-prices/main/data/wti-year.csv"
|
||||
title="Oil Price x Year"
|
||||
xAxis="Date"
|
||||
yAxis="Price"
|
||||
/>
|
||||
|
||||
Or you can add previews
|
||||
|
||||
<FlatUiTable url="https://raw.githubusercontent.com/datasets/oil-prices/main/data/wti-year.csv" />
|
||||
|
||||
And you can of course add markdown
|
||||
|
||||
## Subtitles
|
||||
|
||||
- Lists
|
||||
- Lists
|
||||
|
||||
You can also add mermaid charts
|
||||
|
||||
```mermaid
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
```
|
||||
@@ -0,0 +1,192 @@
|
||||
---
|
||||
title: Frankfurt is Investing in Education, and Your City Should Too
|
||||
date: 06/12/2023
|
||||
authors: ['Michael Polidori']
|
||||
---
|
||||
|
||||
_Note: The currency in this post has been converted to USD using an average exchange rate of 1 EUR = 1.20 USD._
|
||||
|
||||
Between 2008 and 2016, the population of Frankfurt, Germany grew from approximately 670k to 740k[^1], while
|
||||
its spending on education climbed from \$465 million to a staggering \$814 million, a 75% increase. That's a
|
||||
significant surge, bumping education to around 20% of the total budget, only second to social issues.
|
||||
|
||||
The stacked bar chart below (using the [City of Frankfurt Expenditure dataset](https://www.openspending.org/@os-data/city-of-frankfurt-expenditure))
|
||||
helps to bring this data to life. It maps out the city's annual spending across various areas. As you can see,
|
||||
the education slice has grown noticeably over the years, indicating Frankfurt's intention to prioritize this space.
|
||||
The city's commitment to education is abundantly clear.
|
||||
|
||||
<VegaLite
|
||||
spec={{
|
||||
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
|
||||
data: {
|
||||
url: 'https://storage.openspending.org/city-of-frankfurt-expenditure/frankfurt-sums.csv',
|
||||
},
|
||||
transform: [
|
||||
{
|
||||
calculate: "format(datum.amount / 1e6 * 1.20, '$,.1f') + 'M'",
|
||||
as: 'formattedAmountMillion',
|
||||
},
|
||||
{ calculate: 'datum.amount / 1e9 * 1.20', as: 'amountBillion' },
|
||||
],
|
||||
mark: 'bar',
|
||||
width: 350,
|
||||
height: 400,
|
||||
encoding: {
|
||||
x: {
|
||||
field: 'date',
|
||||
type: 'ordinal',
|
||||
title: 'Year',
|
||||
},
|
||||
y: {
|
||||
field: 'amount',
|
||||
type: 'quantitative',
|
||||
title: 'Spending (USD in billions)',
|
||||
axis: {
|
||||
format: '~s',
|
||||
labelExpr: "format(datum.value / 1e9 * 1.20, '$,.0f') + 'B'",
|
||||
},
|
||||
},
|
||||
color: {
|
||||
field: 'label',
|
||||
type: 'nominal',
|
||||
title: 'Area',
|
||||
scale: {
|
||||
domain: [
|
||||
'Building supervision and monument protection',
|
||||
'Business development agency',
|
||||
'Central finance economy',
|
||||
'Central services',
|
||||
'Culture, leisure and sport',
|
||||
'Education',
|
||||
'Elections and superordinate matters',
|
||||
'Environment',
|
||||
'Finance',
|
||||
'Fire protection and emergency services',
|
||||
'Geoinformation and property regulations',
|
||||
'Head of the city administration',
|
||||
'Health',
|
||||
'Local transport and public transport',
|
||||
'Order and security',
|
||||
'Personnel and organization',
|
||||
'Property and building management',
|
||||
'Reside',
|
||||
'Revision and law',
|
||||
'Social issue',
|
||||
'Town planning',
|
||||
],
|
||||
range: [
|
||||
'#EF5350',
|
||||
'#F06292',
|
||||
'#BA68C8',
|
||||
'#9575CD',
|
||||
'#7986CB',
|
||||
'#64B5F6',
|
||||
'#4FC3F7',
|
||||
'#4DD0E1',
|
||||
'#4DB6AC',
|
||||
'#81C784',
|
||||
'#AED581',
|
||||
'#DCE775',
|
||||
'#FFF176',
|
||||
'#FFD54F',
|
||||
'#FFB74D',
|
||||
'#FF8A65',
|
||||
'#A1887F',
|
||||
'#90A4AE',
|
||||
'#78909C',
|
||||
'#546E7A',
|
||||
'#455A64',
|
||||
],
|
||||
},
|
||||
},
|
||||
tooltip: [
|
||||
{ field: 'label', type: 'nominal', title: 'Area' },
|
||||
{
|
||||
field: 'formattedAmountMillion',
|
||||
type: 'ordinal',
|
||||
title: 'Spending (USD in millions)',
|
||||
},
|
||||
{ field: 'date', type: 'ordinal', title: 'Year' },
|
||||
],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
Now, let's look at a line chart that traces only the trajectory of education spending through these eight
|
||||
years (using the same dataset). It's not just a line; it's a testament to Frankfurt's growing conviction that investing in education is
|
||||
the key to a prosperous future.
|
||||
|
||||
<VegaLite
|
||||
spec={{
|
||||
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
|
||||
description: 'Frankfurt Education Spending.',
|
||||
data: {
|
||||
url: 'https://storage.openspending.org/city-of-frankfurt-expenditure/frankfurt-sums.csv',
|
||||
},
|
||||
transform: [
|
||||
{ filter: "datum.label==='Education'" },
|
||||
{
|
||||
calculate: "format(datum.amount / 1e6 * 1.20, '$,.1f') + 'M'",
|
||||
as: 'formattedAmountMillion',
|
||||
},
|
||||
],
|
||||
mark: {
|
||||
type: 'area',
|
||||
line: true,
|
||||
point: true,
|
||||
},
|
||||
width: 400,
|
||||
height: 400,
|
||||
encoding: {
|
||||
x: {
|
||||
field: 'date',
|
||||
type: 'ordinal',
|
||||
title: 'Year',
|
||||
},
|
||||
y: {
|
||||
field: 'amount',
|
||||
type: 'quantitative',
|
||||
title: 'Spending (USD in millions)',
|
||||
axis: {
|
||||
format: '~s',
|
||||
labelExpr: "format(datum.value / 1e6 * 1.20, '$,.0f') + 'M'",
|
||||
},
|
||||
},
|
||||
color: {
|
||||
title: '',
|
||||
field: 'label',
|
||||
scale: {
|
||||
domain: ["Education"],
|
||||
range: ['#64b5f6']
|
||||
},
|
||||
},
|
||||
tooltip: [
|
||||
{ field: 'label', type: 'nominal', title: 'Area' },
|
||||
{
|
||||
field: 'formattedAmountMillion',
|
||||
type: 'ordinal',
|
||||
title: 'Spending (USD in millions)',
|
||||
},
|
||||
{ field: 'date', type: 'ordinal', title: 'Year' },
|
||||
],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
Despite Frankfurt's population experiencing an increase of less than 100k during this period, the significant
|
||||
investment in education tells a different story. It sends a clear message: education isn't merely a line item
|
||||
in their budget—it's their future.
|
||||
|
||||
During this period, it's likely that schools underwent major overhauls, more teachers got hired, new educational
|
||||
programs launched, etc., to give every child in Frankfurt a chance to have an impactful and quality education.
|
||||
|
||||
The beauty of good data is that it's not just numbers—it's narratives. And the narrative here is that Frankfurt
|
||||
is leveraging the power of long-term investment in education for a better, brighter future. This investment in
|
||||
education is not just about the dollars and cents. It's about recognizing the value of quality education to drive
|
||||
social and economic progress.
|
||||
|
||||
Frankfurt is a city that's recognized the power of education, and it's using that power to redefine its future.
|
||||
One can only hope that more cities follow suit.
|
||||
|
||||
[^1]: https://worldpopulationreview.com/world-cities/frankfurt-population
|
||||
|
||||
284
examples/openspending/content/stories/moers-anomaly-2016.mdx
Normal file
284
examples/openspending/content/stories/moers-anomaly-2016.mdx
Normal file
@@ -0,0 +1,284 @@
|
||||
---
|
||||
title: An Exploration of Moers' 2016 Budget Anomaly
|
||||
date: 06/13/2023
|
||||
---
|
||||
|
||||
_Note: The currency in this post has been converted to USD using an average exchange rate of 1 EUR = 1.20 USD.
|
||||
Additionally, the text values for account groups have been loosely translated to English. You can find the
|
||||
original dataset here: [Moers budget dataset](https://www.openspending.org/@os-data/moers-all)_
|
||||
|
||||
In the fiscal landscape of Moers, Germany, 2016 stands out as an anomaly. An examination of the budget allocations
|
||||
for this particular year shows a significant surge in spending across various areas. After this anomalous
|
||||
spike, spending patterns then seemed to resume their previous trajectory of a slow, steady climb in the
|
||||
following years. While it's tempting to dismiss this as an irregularity, it's worth exploring the potential
|
||||
underlying causes of this fiscal fluctuation.
|
||||
|
||||
<VegaLite
|
||||
spec={{
|
||||
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
|
||||
title: 'Spending by Account Group',
|
||||
description: 'Spending by Account Group',
|
||||
data: {
|
||||
url: 'https://storage.openspending.org/moers-all/moers-sums.csv',
|
||||
},
|
||||
transform: [
|
||||
{
|
||||
calculate: "format(datum.amount / 1e6 * 1.20, '$,.1f') + 'M'",
|
||||
as: 'formattedAmountMillion',
|
||||
},
|
||||
{ calculate: 'datum.amount / 1e9 * 1.20', as: 'amountBillion' },
|
||||
],
|
||||
mark: 'bar',
|
||||
height: 400,
|
||||
width: 350,
|
||||
encoding: {
|
||||
x: {
|
||||
field: 'date',
|
||||
type: 'temporal',
|
||||
timeUnit: 'utcyear',
|
||||
title: 'Year',
|
||||
},
|
||||
y: {
|
||||
field: 'amount',
|
||||
type: 'quantitative',
|
||||
title: 'Spending (USD in millions)',
|
||||
axis: {
|
||||
format: '~s',
|
||||
labelExpr: "format(datum.value / 1e6 * 1.20, '$,.0f') + 'M'",
|
||||
},
|
||||
},
|
||||
color: {
|
||||
field: 'account group',
|
||||
type: 'nominal',
|
||||
title: 'Account Group',
|
||||
scale: {
|
||||
domain: [
|
||||
'Activated Own Work',
|
||||
'Balance Expenses',
|
||||
'Care Expenses',
|
||||
'Donations And General Levies',
|
||||
'Expenses For Material And Services',
|
||||
'Extraordinary Expenses',
|
||||
'Extraordinary Income',
|
||||
'Other Ordinary Expenses',
|
||||
'Other Ordinary Income',
|
||||
'Other Transfer Income',
|
||||
'Personnel Expenses',
|
||||
'Private Law Performance Fees',
|
||||
'Public-Service Performance Fees',
|
||||
'Taxes And Similar Charges',
|
||||
'Transfer Expenses',
|
||||
],
|
||||
range: [
|
||||
'#EF5350',
|
||||
'#F06292',
|
||||
'#BA68C8',
|
||||
'#9575CD',
|
||||
'#7986CB',
|
||||
'#64B5F6',
|
||||
'#4FC3F7',
|
||||
'#4DD0E1',
|
||||
'#4DB6AC',
|
||||
'#81C784',
|
||||
'#AED581',
|
||||
'#DCE775',
|
||||
'#FFF176',
|
||||
'#FFD54F',
|
||||
'#FFB74D',
|
||||
],
|
||||
},
|
||||
},
|
||||
tooltip: [
|
||||
{ field: 'account group', type: 'nominal', title: 'Account Group' },
|
||||
{
|
||||
field: 'formattedAmountMillion',
|
||||
type: 'ordinal',
|
||||
title: 'Spending (USD)',
|
||||
},
|
||||
{ field: 'date', type: 'temporal', title: 'Year', format: '%Y' }
|
||||
],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
## Why?
|
||||
|
||||
One possible explanation could be the global refugee crisis that was unfolding around this time, particularly
|
||||
in Germany. While we can't assert this connection definitively due to the lack of specific data, it's an angle
|
||||
worth examining to better understand the budget anomaly of 2016.
|
||||
|
||||
For instance, the "Donations and General Levies" account group saw a distinct increase in 2016. This could be
|
||||
reflective of Moers' attempts to provide immediate support to incoming refugees, although we can only speculate
|
||||
at this point.
|
||||
|
||||
<VegaLite
|
||||
spec={{
|
||||
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
|
||||
title: 'Donations and General Levies',
|
||||
description: 'Donations and General Levies',
|
||||
data: {
|
||||
url: 'https://storage.openspending.org/moers-all/moers-sums.csv',
|
||||
},
|
||||
transform: [
|
||||
{ filter: "datum['account group']==='Donations And General Levies'" },
|
||||
{
|
||||
calculate: "format(datum.amount / 1e6 * 1.20, '$,.1f') + 'M'",
|
||||
as: 'formattedAmountMillion',
|
||||
},
|
||||
],
|
||||
mark: {
|
||||
type: 'area',
|
||||
line: true,
|
||||
point: true,
|
||||
},
|
||||
width: 400,
|
||||
height: 400,
|
||||
encoding: {
|
||||
x: {
|
||||
field: 'date',
|
||||
type: 'temporal',
|
||||
timeUnit: 'utcyear',
|
||||
title: 'Year',
|
||||
},
|
||||
y: {
|
||||
field: 'amount',
|
||||
type: 'quantitative',
|
||||
title: 'Spending (USD in millions)',
|
||||
axis: {
|
||||
format: '~s',
|
||||
labelExpr: "format(datum.value / 1e6 * 1.20, '$,.0f') + 'M'",
|
||||
},
|
||||
},
|
||||
color: {
|
||||
title: 'Account Group',
|
||||
field: 'account group',
|
||||
scale: {
|
||||
domain: ['Donations And General Levies'],
|
||||
range: ['#9575CD'],
|
||||
},
|
||||
},
|
||||
tooltip: [
|
||||
{ field: 'account group', type: 'nominal', title: 'Area' },
|
||||
{
|
||||
field: 'formattedAmountMillion',
|
||||
type: 'ordinal',
|
||||
title: 'Spending (USD in millions)',
|
||||
},
|
||||
{ field: 'date', type: 'temporal', title: 'Year', format: '%Y' }
|
||||
],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
Similarly, "Expenses for Material and Services" also experienced an upswing. This could suggest
|
||||
that the town was working to establish necessary infrastructure and resources for the newcomers. It's plausible
|
||||
that procurement of essential supplies and services to aid the refugees was a factor contributing to this budget
|
||||
increase.
|
||||
|
||||
The rise in "Personnel Expenses" may suggest an expansion of the town's workforce during this period. Additional
|
||||
staffing in areas like interpretation, social work, healthcare, and administration would be necessary to handle
|
||||
the influx of refugees.
|
||||
|
||||
The two account groups that experienced the most substantial raw monetary increases were "Taxes and Similar Charges"
|
||||
and "Transfer Expenses". Both these categories more than doubled in size during the year, a significant surge
|
||||
especially considering their already high baseline spending. This could be for a variety of reasons.
|
||||
|
||||
For "Taxes and Similar Charges", the hike could indicate the town adjusting local taxation to meet the additional
|
||||
expenditures, or it could reflect an increase in income from other sources falling under this group. The influx
|
||||
of refugees and the resulting uptick in economic activity may have also led to a rise in the collection of certain
|
||||
local taxes or fees.
|
||||
|
||||
Concurrently, the "Transfer Expenses" spike could be an indication of heightened social welfare payments, costs
|
||||
associated with refugee integration, and funds transferred to other entities managing the crisis. These financial
|
||||
escalations are a testament to the extensive and multifaceted financial impact the refugee crisis had on the town's
|
||||
budget.
|
||||
|
||||
<VegaLite
|
||||
spec={{
|
||||
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
|
||||
title: 'Largest Spending by Account Group',
|
||||
description: 'Largest Spending by Account Group',
|
||||
data: {
|
||||
url: 'https://storage.openspending.org/moers-all/moers-sums.csv',
|
||||
},
|
||||
transform: [
|
||||
{
|
||||
filter: {
|
||||
field: 'account group',
|
||||
oneOf: [
|
||||
'Donations And General Levies',
|
||||
'Expenses For Material And Services',
|
||||
'Personnel Expenses',
|
||||
'Taxes And Similar Charges',
|
||||
'Transfer Expenses'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
calculate: "format(datum.amount / 1e6 * 1.20, '$,.1f') + 'M'",
|
||||
as: 'formattedAmountMillion',
|
||||
}
|
||||
],
|
||||
mark: {
|
||||
type: 'line',
|
||||
point: true,
|
||||
},
|
||||
width: 400,
|
||||
height: 400,
|
||||
encoding: {
|
||||
x: {
|
||||
field: 'date',
|
||||
type: 'temporal',
|
||||
timeUnit: 'utcyear',
|
||||
title: 'Year'
|
||||
},
|
||||
y: {
|
||||
field: 'amount',
|
||||
type: 'quantitative',
|
||||
title: 'Spending (USD in millions)',
|
||||
axis: {
|
||||
format: '~s',
|
||||
labelExpr: "format(datum.value / 1e6 * 1.20, '$,.0f') + 'M'",
|
||||
}
|
||||
},
|
||||
color: {
|
||||
field: 'account group',
|
||||
type: 'nominal',
|
||||
title: 'Account Group',
|
||||
scale: {
|
||||
domain: [
|
||||
'Donations And General Levies',
|
||||
'Expenses For Material And Services',
|
||||
'Personnel Expenses',
|
||||
'Taxes And Similar Charges',
|
||||
'Transfer Expenses'
|
||||
],
|
||||
range: [
|
||||
'#9575CD',
|
||||
'#7986CB',
|
||||
'#AED581',
|
||||
'#FFD54F',
|
||||
'#FFB74D'
|
||||
],
|
||||
},
|
||||
},
|
||||
tooltip: [
|
||||
{ field: 'account group', type: 'nominal', title: 'Area' },
|
||||
{
|
||||
field: 'formattedAmountMillion',
|
||||
type: 'ordinal',
|
||||
title: 'Spending (USD in millions)',
|
||||
},
|
||||
{ field: 'date', type: 'temporal', title: 'Year', format: '%Y' }
|
||||
],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
By 2017, these budget items returned to their pre-2016 levels, which may suggest that the town had successfully
|
||||
adapted to the new circumstances, perhaps by implementing more cost-effective strategies.
|
||||
|
||||
While this exploration offers a compelling perspective, it's important to note that these are theories derived
|
||||
from the available budget data and the concurrent global events of the time. It underscores how global crises,
|
||||
like the refugee crisis, may potentially impact not just national budgets, but also the fiscal management of
|
||||
smaller towns like Moers.
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: Where does Berlin spends its ERDF benefits?
|
||||
date: 2023-06-12
|
||||
authors: ['João Demenech']
|
||||
---
|
||||
|
||||
In this data-driven story, let's analyze how the city of Berlin has benefited from ERDF from 2008 to 2015.
|
||||
|
||||
## What is ERDF?
|
||||
|
||||
If you're not familiar with ERDF, it's the European Regional Development Fund. According to its [official website](https://ec.europa.eu/regional_policy/funding/erdf_en):
|
||||
|
||||
> The European Regional Development Fund (ERDF) aims to strengthen economic, social and territorial cohesion in the European Union by correcting imbalances between its regions. In 2021-2027 it will enable investments in a smarter, greener, more connected and more social Europe that is closer to its citizens.
|
||||
|
||||
## A look into the data
|
||||
|
||||
The dataset that will be used is this one: https://www.openspending.org/@os-data/de3-berlin-2007-2013-erdf (if you're looking for ERDF data for other cities/regions, take a look at the data catalog).
|
||||
|
||||
Here's a sample of this data:
|
||||
|
||||
<FlatUiTable url="https://storage.openspending.org/de3-berlin-2007-2013-erdf/concat.csv" />
|
||||
|
||||
Note that we will only use the rows where the "amount_kind" column is set to "total_amount".
|
||||
|
||||
## How has the total amount changed over the years?
|
||||
|
||||
The line chart below shows the sum of the total amount of EUR that was approved for each year:
|
||||
|
||||
<LineChart data="https://storage.openspending.org/de3-berlin-2007-2013-erdf/berlin-erdf-2007-2013-total-amount-apporved-per-year.csv" xAxis="approval_year" yAxis="total_amount" />
|
||||
|
||||
As you can see, the total increased significantly from 2007 to 2010, later fluctuating between €7 million and €9 million per year.
|
||||
|
||||
## Who were the top beneficiaries for each year?
|
||||
|
||||
Now, let's try to understand who were the top beneficiaries each year. To do that, let's filter the data to show only the two top beneficiaries for each year:
|
||||
|
||||
<FlatUiTable url="https://storage.openspending.org/de3-berlin-2007-2013-erdf/berlin-erdf-2007-2013-total-amount-approved-per-year-per-beneficiary--top-2.csv" />
|
||||
|
||||
Since there are many years in this range, let's split this analysis into two ranges: one for 2008-2010 and the other for 2011-2015.
|
||||
|
||||
<VegaLite spec={{
|
||||
"data": { "url": "https://storage.openspending.org/de3-berlin-2007-2013-erdf/berlin-erdf-2007-2013-total-amount-approved-per-year-per-beneficiary--top-2.csv"},
|
||||
"transform": [
|
||||
{"filter": "datum.approval_year <= 2010"},
|
||||
],
|
||||
"title": "Total Amount (EUR) x Approval Year (2007-2010)",
|
||||
"width": "container",
|
||||
"mark": {"type": "bar", "tooltip": true },
|
||||
"encoding": {
|
||||
"y": {
|
||||
"aggregate": "sum",
|
||||
"field": "total_amount",
|
||||
"title": "Total Amount (EUR)",
|
||||
"stack": null
|
||||
},
|
||||
"x": {"field": "approval_year", "title": "Approval Year"},
|
||||
"color": {
|
||||
"type": "nominal",
|
||||
"field": "beneficiary_name",
|
||||
}
|
||||
}
|
||||
}} />
|
||||
|
||||
<VegaLite spec={{
|
||||
"title": "Total Amount (EUR) x Approval Year (2011-2013)",
|
||||
"data": { "url": "https://storage.openspending.org/de3-berlin-2007-2013-erdf/berlin-erdf-2007-2013-total-amount-approved-per-year-per-beneficiary--top-2.csv"},
|
||||
"transform": [
|
||||
{"filter": "datum.approval_year > 2010"},
|
||||
],
|
||||
"width": "container",
|
||||
"mark": {"type": "bar", "tooltip": true },
|
||||
"encoding": {
|
||||
"y": {
|
||||
"aggregate": "sum",
|
||||
"field": "total_amount",
|
||||
"title": "Total Amount (EUR)",
|
||||
"stack": null
|
||||
},
|
||||
"x": {"field": "approval_year", "title": "Approval Year"},
|
||||
"color": {
|
||||
"type": "nominal",
|
||||
"field": "beneficiary_name",
|
||||
}
|
||||
}
|
||||
}} />
|
||||
|
||||
It's easy to spot some repeating colors. Now, let's see to which sector the top beneficiaries belong to:
|
||||
|
||||
<Table csv="
|
||||
Beneficiary,Sector
|
||||
D & B,Education
|
||||
Stiftung Sozialpädagogisches Institut Berlin (SPI),Education/Social work
|
||||
IB e.V.,Social work
|
||||
gsub-Projektegesellschaft mbH,Consulting
|
||||
BBW Berufsvorbereitungs-u.Ausbildungsgesellschaft,Education
|
||||
Arbeit und Bildung e.V.,Consulting
|
||||
Gesellschaft für soziale Unternehmensberatung GSUB,Consulting
|
||||
SPI Consult GmbH,Consulting
|
||||
Beuth Hochschule für Technik Berlin,Education
|
||||
TU Berlin, Fakultät II,Education
|
||||
Hochschule für Technik und Wirtschaft Berlin,Education
|
||||
WeTeK gGmbH,Education
|
||||
" />
|
||||
|
||||
Based on the sectors of the top beneficiaries, it's clear that education and professional training have been a major focus of ERDF investment in Berlin during that period of time.
|
||||
@@ -0,0 +1,130 @@
|
||||
---
|
||||
title: Where the European Structural and Investment Funds go?
|
||||
date: 2023-06-08
|
||||
authors: ['Anuar Ustayev']
|
||||
---
|
||||
|
||||
European Structural and Investment Funds (ESIF) is a financial instrument used by the European Union (EU) to support regional development and economic cohesion among its member states. The ESIF combines several funds to provide financial assistance to regions and cities in the EU with the aim of reducing economic disparities and promoting sustainable growth.
|
||||
|
||||
In this data story, our objective is to determine which country benefits the most from the ESIF funds and identify the region within the EU that receives the highest amount of funding.
|
||||
|
||||
To begin our analysis, we are using data on the allocation of ESIF funds across EU member states and their respective regions. These datasets are provided by previous work at OpenSpending project. See available datasets:
|
||||
|
||||
- Full dataset: https://www.openspending.org/@os-data/complete-european-esif-funds-beneficiaries-2007-2020
|
||||
- By country, e.g., this is for Austria: https://www.openspending.org/@os-data/complete-european-esif-funds-beneficiaries-2007-2020-filtered-by-at
|
||||
|
||||
The data provide insights into the financial assistance provided by the European Union to support regional development and economic cohesion:
|
||||
|
||||
<FlatUiTable url="https://storage.openspending.org/complete-european-esif-funds-beneficiaries-2007-2020/eu-esif-funds-beneficiaries-2007-2020-full.csv" />
|
||||
|
||||
After processing the available datasets we have derived an aggregated data resource that groups data by country which enables us to understand where the most funding went between 2007 and 2020. Notice that maximum amounts in each column are highlighted in the table but they might be in local currencies so check the 'currency' field:
|
||||
|
||||
<FlatUiTable url="https://storage.openspending.org/eu-esif-funds-beneficiaries-2007-2020-full-aggregated-by-country.csv" />
|
||||
|
||||
Quick observations:
|
||||
|
||||
- The Czech Republic has the EU cofinancing amount of CZK 2,731,165,279,234 which is approximately EUR 115 billions.
|
||||
- Poland has the EU cofinancing amount of PLN 302,958,765,476 which is approximately EUR 67 billions.
|
||||
- Other countries that use local currencies do not have significant amounts when comparing to above two nations.
|
||||
|
||||
So let's convert all currencies to ~EUR but only include 'eu_cofinancing_amount' values as we will use it for comparison:
|
||||
|
||||
<FlatUiTable url="https://storage.openspending.org/eu-esif-funds-beneficiaries-2007-2020--country-code-confinancing-amount.csv" />
|
||||
|
||||
With this data table we can easily see top countries by funding. Note that you can use the table component above to sort values by values in 'eu_cofinancing_amount' column which helps you to quickly see top countries. Let's build a quick visualization to make it even more obvious:
|
||||
|
||||
<Vega
|
||||
data={{
|
||||
table: [
|
||||
{
|
||||
x: "LU",
|
||||
y: 30852529.89
|
||||
},
|
||||
{
|
||||
x: "DK",
|
||||
y: 492017672
|
||||
},
|
||||
{
|
||||
x: "BE",
|
||||
y: 858388537.42
|
||||
},
|
||||
{
|
||||
x: "DE",
|
||||
y: 912803359.21
|
||||
},
|
||||
{
|
||||
x: "FI",
|
||||
y: 2858282488
|
||||
},
|
||||
{
|
||||
x: "SI",
|
||||
y: 4576151396.24
|
||||
},
|
||||
{
|
||||
x: "EE",
|
||||
y: 5419641772
|
||||
},
|
||||
{
|
||||
x: "LT",
|
||||
y: 6750675528.74
|
||||
},
|
||||
{
|
||||
x: "SK",
|
||||
y: 12295960193.92
|
||||
},
|
||||
{
|
||||
x: "UK",
|
||||
y: 12829255012.1
|
||||
},
|
||||
{
|
||||
x: "FR",
|
||||
y: 15027864492.94
|
||||
},
|
||||
{
|
||||
x: "RO",
|
||||
y: 19970864938.12
|
||||
},
|
||||
{
|
||||
x: "PT",
|
||||
y: 23800568868.02
|
||||
},
|
||||
{
|
||||
x: "IT",
|
||||
y: 34860253672.98
|
||||
},
|
||||
{
|
||||
x: "PL",
|
||||
y: 67537688711
|
||||
},
|
||||
{
|
||||
x: "CZ",
|
||||
y: 115591108113
|
||||
}
|
||||
]
|
||||
}}
|
||||
spec={{
|
||||
$schema: 'https://vega.github.io/schema/vega-lite/v4.json',
|
||||
data: {
|
||||
name: 'table'
|
||||
},
|
||||
encoding: {
|
||||
x: {
|
||||
field: 'x',
|
||||
type: 'ordinal'
|
||||
},
|
||||
y: {
|
||||
field: 'y',
|
||||
type: 'quantitative'
|
||||
}
|
||||
},
|
||||
mark: 'bar'
|
||||
}}
|
||||
/>
|
||||
|
||||
Based on the bar chart above we can conclude that the following 3 countries have received the most amounts from ESIF fund:
|
||||
|
||||
1. Czech Republic - EUR ~116b.
|
||||
2. Poland - EUR ~68b.
|
||||
3. Italy - EUR ~35b.
|
||||
|
||||
_This data story was created by using Datopian's PortalJS framework. You can learn more about the framework by visiting https://portaljs.org/_
|
||||
@@ -2,7 +2,7 @@
|
||||
import { remark } from "remark";
|
||||
import stripMarkdown, { Options } from "strip-markdown";
|
||||
|
||||
import { defaultConfig as siteConfig } from '@flowershow/core'
|
||||
import { defaultConfig as siteConfig } from '@portaljs/core'
|
||||
|
||||
// TODO return type
|
||||
const sluggify = (urlPath: string) => {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import matter from "gray-matter";
|
||||
import mdxmermaid from "mdx-mermaid";
|
||||
import { h } from "hastscript";
|
||||
import remarkCallouts from "@flowershow/remark-callouts";
|
||||
import remarkEmbed from "@flowershow/remark-embed";
|
||||
import remarkCallouts from "@portaljs/remark-callouts";
|
||||
import remarkEmbed from "@portaljs/remark-embed";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import remarkMath from "remark-math";
|
||||
import remarkSmartypants from "remark-smartypants";
|
||||
import remarkToc from "remark-toc";
|
||||
import remarkWikiLink from "@flowershow/remark-wiki-link";
|
||||
import remarkWikiLink from "@portaljs/remark-wiki-link";
|
||||
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
||||
import rehypeKatex from "rehype-katex";
|
||||
import rehypeSlug from "rehype-slug";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MarkdownDB } from "@flowershow/markdowndb";
|
||||
import { MarkdownDB } from "mddb";
|
||||
// import config from "./markdowndb.config.js";
|
||||
|
||||
// TODO get this path from markdowndb.config.js or something
|
||||
|
||||
3821
examples/openspending/package-lock.json
generated
3821
examples/openspending/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,53 +12,55 @@
|
||||
"test": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/plugin-throttling": "^5.2.2",
|
||||
"@types/flexsearch": "^0.7.3",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
"datapackage": "^1.1.10",
|
||||
"flexsearch": "0.7.21",
|
||||
"next-seo": "^6.0.0",
|
||||
"octokit": "^2.0.14",
|
||||
"prettier": "^2.8.8",
|
||||
"react-hook-form": "^7.43.9",
|
||||
"react-markdown": "^8.0.7",
|
||||
"react-timeago": "^7.1.0",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"remark": "^14.0.3",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"strip-markdown": "^5.0.1",
|
||||
"@flowershow/core": "^0.4.13",
|
||||
"@flowershow/markdowndb": "^0.1.5",
|
||||
"@flowershow/remark-callouts": "^1.0.0",
|
||||
"@flowershow/remark-embed": "^1.0.0",
|
||||
"@flowershow/markdowndb": "^0.1.8",
|
||||
"@githubocto/flat-ui": "^0.14.1",
|
||||
"@headlessui/react": "^1.7.14",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"@octokit/plugin-throttling": "^5.2.2",
|
||||
"@portaljs/ckan": "^0.0.2",
|
||||
"@portaljs/components": "^0.1.8",
|
||||
"@portaljs/core": "^1.0.5",
|
||||
"@portaljs/remark-callouts": "^1.0.5",
|
||||
"@portaljs/remark-embed": "^1.0.4",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@types/flexsearch": "^0.7.3",
|
||||
"@types/node": "20.2.3",
|
||||
"@types/react": "18.2.6",
|
||||
"@types/react-dom": "18.2.4",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"autoprefixer": "10.4.14",
|
||||
"clsx": "^1.2.1",
|
||||
"datapackage": "^1.1.10",
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-next": "13.4.3",
|
||||
"flexsearch": "0.7.21",
|
||||
"isomorphic-unfetch": "^4.0.2",
|
||||
"mddb": "^0.1.9",
|
||||
"next": "13.4.3",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"next-seo": "^6.0.0",
|
||||
"octokit": "^2.0.14",
|
||||
"papaparse": "^5.4.1",
|
||||
"postcss": "8.4.23",
|
||||
"prettier": "^2.8.8",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.43.9",
|
||||
"react-markdown": "^8.0.7",
|
||||
"react-query": "^3.39.3",
|
||||
"react-timeago": "^7.1.0",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"rehype-katex": "^6.0.3",
|
||||
"rehype-prism-plus": "^1.5.1",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"rehype-slug": "^5.1.0",
|
||||
"remark": "^14.0.3",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-math": "^5.1.1",
|
||||
"remark-smartypants": "^2.0.0",
|
||||
"remark-toc": "^8.0.1",
|
||||
"strip-markdown": "^5.0.1",
|
||||
"tailwindcss": "3.3.2",
|
||||
"typescript": "5.0.4"
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
ThemeProvider,
|
||||
NavItem,
|
||||
NavGroup,
|
||||
} from '@flowershow/core';
|
||||
} from '@portaljs/core';
|
||||
|
||||
export interface CustomAppProps {
|
||||
meta: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs';
|
||||
import React from 'react';
|
||||
import { GetStaticProps } from 'next';
|
||||
import { BlogsList, SimpleLayout } from '@flowershow/core';
|
||||
import { BlogsList, SimpleLayout } from '@portaljs/core';
|
||||
import clientPromise from '../lib/mddb';
|
||||
import type { CustomAppProps } from './_app';
|
||||
import Layout from '@/components/_shared/Layout';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs';
|
||||
import React from 'react';
|
||||
import { GetStaticProps } from 'next';
|
||||
import { BlogsList, SimpleLayout } from '@flowershow/core';
|
||||
import { BlogsList, SimpleLayout } from '@portaljs/core';
|
||||
import clientPromise from '../../lib/mddb';
|
||||
import type { CustomAppProps } from '../_app';
|
||||
import Layout from '@/components/_shared/Layout';
|
||||
|
||||
@@ -86,7 +86,7 @@ pre {
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import "@flowershow/remark-callouts/styles.css";
|
||||
@import "@portaljs/remark-callouts/styles.css";
|
||||
|
||||
.w-5 {
|
||||
width: 1.25rem
|
||||
@@ -178,13 +178,3 @@ a {
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html {
|
||||
color-scheme: dark;
|
||||
}
|
||||
body {
|
||||
color: white;
|
||||
background: black;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ module.exports = {
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./node_modules/@flowershow/core/dist/*.js",
|
||||
"./node_modules/@flowershow/core/*.js",
|
||||
"./node_modules/@portaljs/core/dist/*.js",
|
||||
"./node_modules/@portaljs/core/*.js",
|
||||
],
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import matter from "gray-matter";
|
||||
import mdxmermaid from "mdx-mermaid";
|
||||
import { h } from "hastscript";
|
||||
import remarkCallouts from "@flowershow/remark-callouts";
|
||||
import remarkEmbed from "@flowershow/remark-embed";
|
||||
import remarkCallouts from "@portaljs/remark-callouts";
|
||||
import remarkEmbed from "@portaljs/remark-embed";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import remarkMath from "remark-math";
|
||||
import remarkSmartypants from "remark-smartypants";
|
||||
import remarkToc from "remark-toc";
|
||||
import remarkWikiLink from "@flowershow/remark-wiki-link";
|
||||
import remarkWikiLink from "@portaljs/remark-wiki-link";
|
||||
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
||||
import rehypeKatex from "rehype-katex";
|
||||
import rehypeSlug from "rehype-slug";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MarkdownDB } from "@flowershow/markdowndb";
|
||||
import { MarkdownDB } from "mddb";
|
||||
|
||||
const dbPath = "markdown.db";
|
||||
|
||||
|
||||
1252
examples/turing/package-lock.json
generated
1252
examples/turing/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,11 +12,6 @@
|
||||
},
|
||||
"browserslist": "defaults, not ie <= 11",
|
||||
"dependencies": {
|
||||
"@flowershow/core": "^0.4.10",
|
||||
"@flowershow/markdowndb": "^0.1.1",
|
||||
"@flowershow/remark-callouts": "^1.0.0",
|
||||
"@flowershow/remark-embed": "^1.0.0",
|
||||
"@flowershow/remark-wiki-link": "^1.1.2",
|
||||
"@headlessui/react": "^1.7.13",
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@mapbox/rehype-prism": "^0.8.0",
|
||||
@@ -24,6 +19,10 @@
|
||||
"@mdx-js/react": "^2.1.5",
|
||||
"@next/mdx": "^13.0.2",
|
||||
"@opentelemetry/api": "^1.4.0",
|
||||
"@portaljs/core": "^1.0.5",
|
||||
"@portaljs/remark-callouts": "^1.0.5",
|
||||
"@portaljs/remark-embed": "^1.0.4",
|
||||
"@portaljs/remark-wiki-link": "^1.0.4",
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"@tailwindcss/typography": "^0.5.4",
|
||||
"@tanstack/react-table": "^8.8.5",
|
||||
@@ -35,6 +34,7 @@
|
||||
"focus-visible": "^5.2.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hastscript": "^7.2.0",
|
||||
"mddb": "^0.1.9",
|
||||
"mdx-mermaid": "^2.0.0-rc7",
|
||||
"mermaid": "^10.1.0",
|
||||
"next": "13.2.1",
|
||||
@@ -60,12 +60,12 @@
|
||||
"tailwindcss": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "18.16.0",
|
||||
"@types/react": "18.2.0",
|
||||
"@types/react-dom": "18.2.0",
|
||||
"eslint": "8.26.0",
|
||||
"eslint-config-next": "13.0.2",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier-plugin-tailwindcss": "^0.2.6",
|
||||
"@types/node": "18.16.0",
|
||||
"@types/react": "18.2.0",
|
||||
"@types/react-dom": "18.2.0"
|
||||
"prettier-plugin-tailwindcss": "^0.2.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { MDXRemote } from 'next-mdx-remote'
|
||||
import { Card } from '../components/Card'
|
||||
import Head from 'next/head'
|
||||
import parse from '../lib/markdown'
|
||||
import { Mermaid } from '@flowershow/core';
|
||||
import { Mermaid } from '@portaljs/core';
|
||||
|
||||
export const getStaticProps = async ({ params }) => {
|
||||
const urlPath = params.slug ? params.slug.join('/') : ''
|
||||
|
||||
7147
package-lock.json
generated
7147
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@@ -5,7 +5,6 @@
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"changeset": "changeset",
|
||||
"prerelease": "nx affected --targets=lint,test",
|
||||
"release": "changeset publish"
|
||||
},
|
||||
"private": true,
|
||||
@@ -14,11 +13,11 @@
|
||||
"@changesets/changelog-github": "^0.4.8",
|
||||
"@changesets/cli": "^2.26.1",
|
||||
"@nrwl/cypress": "15.9.2",
|
||||
"@nrwl/eslint-plugin-nx": "^16.0.2",
|
||||
"@nrwl/eslint-plugin-nx": "15.9.2",
|
||||
"@nrwl/jest": "15.9.2",
|
||||
"@nrwl/js": "15.9.2",
|
||||
"@nrwl/linter": "15.9.2",
|
||||
"@nrwl/next": "^15.9.2",
|
||||
"@nrwl/next": "15.9.2",
|
||||
"@nrwl/react": "15.9.2",
|
||||
"@nrwl/rollup": "15.9.2",
|
||||
"@nrwl/workspace": "15.9.2",
|
||||
@@ -28,13 +27,16 @@
|
||||
"@swc/helpers": "~0.5.0",
|
||||
"@swc/jest": "0.2.20",
|
||||
"@testing-library/react": "14.0.0",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@types/node": "18.14.2",
|
||||
"@types/react": "18.0.28",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
||||
"@typescript-eslint/parser": "^5.36.1",
|
||||
"babel-jest": "^29.4.1",
|
||||
"chai": "^4.3.7",
|
||||
"cypress": "^12.2.0",
|
||||
"eslint": "~8.15.0",
|
||||
"eslint-config-next": "13.1.1",
|
||||
@@ -44,14 +46,21 @@
|
||||
"eslint-plugin-jsx-a11y": "6.7.1",
|
||||
"eslint-plugin-react": "7.32.2",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"htmlparser2": "^9.0.0",
|
||||
"jest": "^29.4.1",
|
||||
"jest-environment-jsdom": "^29.4.1",
|
||||
"micromark": "^3.2.0",
|
||||
"mocha": "^10.2.0",
|
||||
"nx": "15.9.2",
|
||||
"prettier": "^2.6.2",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"rehype-stringify": "^9.0.3",
|
||||
"remark": "^14.0.3",
|
||||
"swc-loader": "0.1.15",
|
||||
"ts-jest": "^29.0.5",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "~4.9.5"
|
||||
"typescript": "~4.9.5",
|
||||
"unist-util-select": "^4.0.3",
|
||||
"unist-util-visit": "^4.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
7
packages/ckan/CHANGELOG.md
Normal file
7
packages/ckan/CHANGELOG.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# @portaljs/ckan
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`e82e2ae`](https://github.com/datopian/portaljs/commit/e82e2ae0211ea3e4701703d353b44cf1001434ef) Thanks [@olayway](https://github.com/olayway)! - Fix: replace deprecated `prepublish` script with `prepare`
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@portaljs/ckan",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.3",
|
||||
"type": "module",
|
||||
"description": "https://portaljs.org",
|
||||
"keywords": [
|
||||
@@ -13,7 +13,8 @@
|
||||
"scripts": {
|
||||
"build": "tsc && vite build && npm run build-tailwind",
|
||||
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"build-tailwind": "NODE_ENV=production npx tailwindcss -o ./dist/styles.css --minify"
|
||||
"build-tailwind": "NODE_ENV=production npx tailwindcss -o ./dist/styles.css --minify",
|
||||
"prepare": "npm run build"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0",
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @portaljs/components
|
||||
|
||||
## 0.1.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#960](https://github.com/datopian/portaljs/pull/960) [`add2f6d0`](https://github.com/datopian/portaljs/commit/add2f6d0f372434eb996d59d6faf5cd06530c932) Thanks [@demenech](https://github.com/demenech)! - Fix width of the <LineChart /> component
|
||||
|
||||
## 0.1.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`e82e2ae`](https://github.com/datopian/portaljs/commit/e82e2ae0211ea3e4701703d353b44cf1001434ef) Thanks [@olayway](https://github.com/olayway)! - Fix: replace deprecated `prepublish` script with `prepare`
|
||||
|
||||
## 0.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`40d80d2`](https://github.com/datopian/portaljs/commit/40d80d2282bf8464c1aafb393975065078ad9ea3) Thanks [@olayway](https://github.com/olayway)! - Fix: missing files in the published package.
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#933](https://github.com/datopian/portaljs/pull/933) [`683159d`](https://github.com/datopian/portaljs/commit/683159da02708ce520e9aad9707f2b96b598ec8b) Thanks [@demenech](https://github.com/demenech)! - More params added to <LineChart />, loading spinners added to <Table /> and <LineChart />, minor fixes
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@portaljs/components",
|
||||
"version": "0.1.8",
|
||||
"version": "0.1.12",
|
||||
"type": "module",
|
||||
"description": "https://portaljs.org",
|
||||
"keywords": [
|
||||
@@ -16,7 +16,8 @@
|
||||
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build",
|
||||
"build-tailwind": "NODE_ENV=production npx tailwindcss -o ./dist/styles.css --minify"
|
||||
"build-tailwind": "NODE_ENV=production npx tailwindcss -o ./dist/styles.css --minify",
|
||||
"prepare": "npm run build"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0",
|
||||
|
||||
@@ -35,7 +35,7 @@ export function LineChart({
|
||||
const spec = {
|
||||
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
|
||||
title,
|
||||
width: 600,
|
||||
width: 'container',
|
||||
height: 300,
|
||||
mark: {
|
||||
type: 'line',
|
||||
|
||||
12
packages/core/.babelrc
Normal file
12
packages/core/.babelrc
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@nrwl/react/babel",
|
||||
{
|
||||
"runtime": "automatic",
|
||||
"useBuiltIns": "usage"
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": []
|
||||
}
|
||||
18
packages/core/.eslintrc.json
Normal file
18
packages/core/.eslintrc.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*", "dist/**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
37
packages/core/CHANGELOG.md
Normal file
37
packages/core/CHANGELOG.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# @portaljs/core
|
||||
|
||||
## 1.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#958](https://github.com/datopian/portaljs/pull/958) [`c4bf5bd0`](https://github.com/datopian/portaljs/commit/c4bf5bd05401982125750e61a27ed31f9bb14a4d) Thanks [@olayway](https://github.com/olayway)! - Add basic Hero component.
|
||||
|
||||
## 1.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`6f0da8c3`](https://github.com/datopian/portaljs/commit/6f0da8c3a3cde4dc7512c6529eb662de6f4fe56a) Thanks [@olayway](https://github.com/olayway)! - Fix public API (`exports`, `types`, and `main` fields in `package.json`).
|
||||
|
||||
## 1.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`6bf6c8fa`](https://github.com/datopian/portaljs/commit/6bf6c8faf4eefc2b0a7f309d83ba8aac19141bb7) Thanks [@olayway](https://github.com/olayway)! - Bump mdx-mermaid to v2.0.0-rc7 as a workaround for [mermaid import tag showing at the top of pages as plain text](https://github.com/sjwall/mdx-mermaid/issues/88), and move it to peer-dependencies.
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`e82e2ae`](https://github.com/datopian/portaljs/commit/e82e2ae0211ea3e4701703d353b44cf1001434ef) Thanks [@olayway](https://github.com/olayway)! - Fix: replace deprecated `prepublish` script with `prepare`
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`40d80d2`](https://github.com/datopian/portaljs/commit/40d80d2282bf8464c1aafb393975065078ad9ea3) Thanks [@olayway](https://github.com/olayway)! - Fix: missing files in the published package.
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`b7158a5`](https://github.com/datopian/portaljs/commit/b7158a5be668018d9b947f9c9d63fa30fa91d18b) Thanks [@olayway](https://github.com/olayway)! - Fix what's getting published to npm.
|
||||
3
packages/core/README.md
Normal file
3
packages/core/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# @portaljs/core
|
||||
|
||||
Core Portal.JS package containing components, styles, and utils.
|
||||
9
packages/core/jest.config.ts
Normal file
9
packages/core/jest.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: "core",
|
||||
preset: "../../jest.preset.js",
|
||||
transform: {
|
||||
"^.+\\.[tj]sx?$": "babel-jest",
|
||||
},
|
||||
moduleFileExtensions: ["ts", "tsx", "js", "jsx"]
|
||||
};
|
||||
55
packages/core/package.json
Normal file
55
packages/core/package.json
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "@portaljs/core",
|
||||
"version": "1.0.6",
|
||||
"description": "Core Portal.JS components, configs and utils.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/datopian/portaljs.git",
|
||||
"directory": "packages/core"
|
||||
},
|
||||
"author": "Rufus Pollock",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/datopian/portaljs/issues"
|
||||
},
|
||||
"homepage": "https://github.com/datopian/portaljs#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "nx build core"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"type": "module",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/src/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/src/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@docsearch/react": "^3.3.3",
|
||||
"@floating-ui/react-dom": "^1.3.0",
|
||||
"@floating-ui/react-dom-interactions": "^0.13.3",
|
||||
"@giscus/react": "^2.2.6",
|
||||
"@headlessui/react": "^1.7.12",
|
||||
"clsx": "^1.2.1",
|
||||
"core-js": "^3.30.2",
|
||||
"disqus-react": "^1.1.5",
|
||||
"framer-motion": "^10.0.1",
|
||||
"kbar": "0.1.0-beta.40",
|
||||
"mermaid": "^10.2.2",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": "^13.2.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"mdx-mermaid": "2.0.0-rc7"
|
||||
}
|
||||
}
|
||||
39
packages/core/project.json
Normal file
39
packages/core/project.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "core",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/core/src",
|
||||
"projectType": "library",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nrwl/rollup:rollup",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "packages/core/dist",
|
||||
"tsConfig": "packages/core/tsconfig.lib.json",
|
||||
"project": "packages/core/package.json",
|
||||
"entryFile": "packages/core/src/index.ts",
|
||||
"format": ["esm"],
|
||||
"generateExportsField": true,
|
||||
"rollupConfig": "@nrwl/react/plugins/bundle-rollup",
|
||||
"compiler": "babel",
|
||||
"assets": []
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["packages/core/**/*.{ts,tsx,js,jsx}"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "packages/core/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
packages/core/src/config/default.ts
Normal file
31
packages/core/src/config/default.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
export const defaultConfig = {
|
||||
title: "Flowershow",
|
||||
description: "",
|
||||
showEditLink: false,
|
||||
showToc: true,
|
||||
showSidebar: false,
|
||||
showLinkPreviews: true,
|
||||
author: "",
|
||||
authorLogo: "",
|
||||
domain: "",
|
||||
// Google analytics key e.g. G-XXXX
|
||||
analytics: "",
|
||||
// content source directory for markdown files
|
||||
// DO NOT CHANGE THIS VALUE
|
||||
// if you have your notes in another (external) directory,
|
||||
// /content dir should be a symlink to that directory
|
||||
content: "content",
|
||||
avatarPlaceholder: "/_flowershow/avatarplaceholder.png",
|
||||
contentExclude: [],
|
||||
contentInclude: [],
|
||||
blogDir: "blog",
|
||||
peopleDir: "people",
|
||||
// Theme
|
||||
theme: {
|
||||
default: "dark",
|
||||
toggleIcon: "/_flowershow/theme-button.svg",
|
||||
},
|
||||
navLinks: [
|
||||
// { href: '/about', name: 'About' },
|
||||
],
|
||||
};
|
||||
1
packages/core/src/config/index.ts
Normal file
1
packages/core/src/config/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { defaultConfig } from "./default";
|
||||
3
packages/core/src/index.ts
Normal file
3
packages/core/src/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./ui";
|
||||
export * from "./utils";
|
||||
export * from "./config";
|
||||
7
packages/core/src/types/index.d.ts
vendored
Normal file
7
packages/core/src/types/index.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
gtag: any; // TODO
|
||||
}
|
||||
}
|
||||
24
packages/core/src/ui/Avatar/Avatar.tsx
Normal file
24
packages/core/src/ui/Avatar/Avatar.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
// TODO
|
||||
type Props = any;
|
||||
|
||||
export const Avatar: React.FC<Props> = ({ name, img, href }) => {
|
||||
const Component = href ? "a" : "div";
|
||||
return (
|
||||
<Component href={href} className="group block flex-shrink-0 mt-2">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div>
|
||||
<img
|
||||
className="inline-block h-9 w-9 rounded-full"
|
||||
src={img}
|
||||
alt={name}
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<p className="text-sm font-medium text-primary dark:text-primary-dark">
|
||||
{name}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
1
packages/core/src/ui/Avatar/index.ts
Normal file
1
packages/core/src/ui/Avatar/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { Avatar } from "./Avatar";
|
||||
15
packages/core/src/ui/Base/BaseLink.tsx
Normal file
15
packages/core/src/ui/Base/BaseLink.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import Link from "next/link.js";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
const BaseLink = forwardRef((props: any, ref) => {
|
||||
const { href, children, ...rest } = props;
|
||||
return (
|
||||
<Link href={href} ref={ref} {...rest}>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
});
|
||||
|
||||
BaseLink.displayName = "BaseLink";
|
||||
|
||||
export { BaseLink };
|
||||
57
packages/core/src/ui/Base/CustomLink.tsx
Normal file
57
packages/core/src/ui/Base/CustomLink.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import Link from "next/link.js";
|
||||
import { Tooltip } from "../Tooltip";
|
||||
import TwitterEmbed from "./TwitterEmbed";
|
||||
|
||||
// TODO it's a mess, move twitter embeds support to remark-embed
|
||||
const TWITTER_REGEX =
|
||||
/^https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(es)?\/(\d+)/;
|
||||
|
||||
interface Props {
|
||||
href: string;
|
||||
data: any;
|
||||
usehook: any;
|
||||
preview: boolean;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
[x: string]: unknown;
|
||||
}
|
||||
|
||||
export const CustomLink: React.FC<Props> = ({
|
||||
data,
|
||||
usehook,
|
||||
preview,
|
||||
...props
|
||||
}) => {
|
||||
const { href } = props;
|
||||
const isInternalLink = !href.startsWith("http");
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
const isHeadingLink = href.startsWith("#");
|
||||
const isTwitterLink = TWITTER_REGEX.test(href);
|
||||
|
||||
// Use next link for pages within app and <a> for external links.
|
||||
// https://nextjs.org/learn/basics/navigate-between-pages/client-side
|
||||
if (isInternalLink) {
|
||||
if (preview && !isHeadingLink) {
|
||||
return (
|
||||
<Tooltip
|
||||
{...props}
|
||||
data={data} // TODO again, why do we pass all documents here?!
|
||||
usehook={usehook}
|
||||
render={(tooltipTriggerProps) => <Link {...tooltipTriggerProps} />}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return <Link {...props} />;
|
||||
}
|
||||
}
|
||||
|
||||
if (isTwitterLink) {
|
||||
return <TwitterEmbed url={href} {...props} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<a target="_blank" rel="noopener noreferrer" {...props}>
|
||||
{props.children}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
44
packages/core/src/ui/Base/ThemeSelector.tsx
Normal file
44
packages/core/src/ui/Base/ThemeSelector.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { useTheme } from "next-themes";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface Props {
|
||||
defaultTheme: "dark" | "light";
|
||||
toggleIcon: string;
|
||||
}
|
||||
|
||||
export const ThemeSelector: React.FC<Props> = ({
|
||||
defaultTheme,
|
||||
toggleIcon,
|
||||
}) => {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
useEffect(() => setMounted(true), []);
|
||||
|
||||
/** Avoid Hydration Mismatch
|
||||
* https://github.com/pacocoursey/next-themes#avoid-hydration-mismatch
|
||||
*/
|
||||
if (!mounted) return null;
|
||||
|
||||
// TODO why?
|
||||
if (!defaultTheme) return null;
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={`
|
||||
min-w-fit transition duration-500
|
||||
${theme === "dark" ? "grayscale opacity-70" : ""}
|
||||
`}
|
||||
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
|
||||
>
|
||||
<img
|
||||
src={toggleIcon}
|
||||
alt="toggle theme"
|
||||
width={24}
|
||||
height={24}
|
||||
className="max-w-24 max-h-24"
|
||||
/>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
105
packages/core/src/ui/Base/TwitterEmbed.tsx
Normal file
105
packages/core/src/ui/Base/TwitterEmbed.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
// TODO dark and light theme
|
||||
|
||||
import { useEffect, useState, useRef, RefObject } from "react";
|
||||
|
||||
const twitterWidgetJs = "https://platform.twitter.com/widgets.js";
|
||||
enum TweetState {
|
||||
LOADING,
|
||||
LOADED,
|
||||
FAILED,
|
||||
}
|
||||
|
||||
interface TweetConfig {
|
||||
theme: string;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
twttr: {
|
||||
widgets: {
|
||||
createTweet: (
|
||||
id: string,
|
||||
ref: RefObject<HTMLDivElement>,
|
||||
options: TweetConfig
|
||||
) => Promise<any>; // TODO type
|
||||
load: (ref: RefObject<HTMLDivElement>) => void;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default function TwitterEmbed({ url, ...props }) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
const [tweetState, setTweetState] = useState<TweetState>(TweetState.LOADING);
|
||||
|
||||
const tweetId = url.split("status/").pop();
|
||||
|
||||
useEffect(() => {
|
||||
const renderTweet = () => {
|
||||
window.twttr.widgets
|
||||
.createTweet(tweetId, ref.current as any, {
|
||||
theme: "dark",
|
||||
})
|
||||
.then((el) => {
|
||||
if (el) {
|
||||
setTweetState(TweetState.LOADED);
|
||||
} else {
|
||||
setTweetState(TweetState.FAILED);
|
||||
}
|
||||
});
|
||||
return window.twttr.widgets.load(ref.current as any);
|
||||
};
|
||||
|
||||
if (!window.twttr) {
|
||||
const script = document.createElement("script");
|
||||
script.src = twitterWidgetJs;
|
||||
script.async = true;
|
||||
script.onload = () => renderTweet();
|
||||
document.head.appendChild(script);
|
||||
} else {
|
||||
renderTweet();
|
||||
}
|
||||
}, [tweetId]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{tweetState === TweetState.LOADING && (
|
||||
<div className="relative my-4 w-full sm:max-w-xl bg-neutral-900 drop-shadow-md rounded-lg">
|
||||
<div className="absolute flex flex-col flex-wrap break-all items-center justify-center bg-slate-700/60 w-full h-full px-4 py-2 rounded-lg top-0 left-0 z-10">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-6 absolute right-4 top-4"
|
||||
>
|
||||
<title>Twitter</title>
|
||||
<path
|
||||
fill="#1DA1F2"
|
||||
d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"
|
||||
/>
|
||||
</svg>
|
||||
<div className="text-gray-300 font-bold my-2 italic">
|
||||
{"Loading tweet..."}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 space-y-4 animate-pulse">
|
||||
<div className="flex items-center">
|
||||
<div className="mr-2 h-10 w-10 rounded-full bg-slate-700" />
|
||||
<div className="w-1/3 h-4 bg-slate-700"></div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="w-2/3 h-3 bg-slate-700"></div>
|
||||
<div className="w-2/3 h-3 bg-slate-700"></div>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<div className="w-1/4 h-3 bg-slate-700"></div>
|
||||
<div className="w-1/4 h-3 bg-slate-700"></div>
|
||||
<div className="w-1/4 h-3 bg-slate-700"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="twitter-tweet" ref={ref} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
3
packages/core/src/ui/Base/index.ts
Normal file
3
packages/core/src/ui/Base/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { BaseLink } from "./BaseLink";
|
||||
export { ThemeSelector } from "./ThemeSelector";
|
||||
export { CustomLink } from "./CustomLink";
|
||||
21
packages/core/src/ui/Blog/Avatar.jsx
Normal file
21
packages/core/src/ui/Blog/Avatar.jsx
Normal file
@@ -0,0 +1,21 @@
|
||||
export function Avatar({ name, img, href }) {
|
||||
const Component = href ? "a" : "div";
|
||||
return (
|
||||
<Component href={href} className="group block flex-shrink-0 mt-2">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div>
|
||||
<img
|
||||
className="inline-block h-9 w-9 rounded-full"
|
||||
src={img}
|
||||
alt={name}
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<p className="text-sm font-medium text-primary dark:text-primary-dark">
|
||||
{name}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
40
packages/core/src/ui/Blog/BlogItem.tsx
Normal file
40
packages/core/src/ui/Blog/BlogItem.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Card } from "../Card";
|
||||
import { formatDate } from "../../utils/formatDate";
|
||||
import { Blog } from "../types";
|
||||
|
||||
interface Props {
|
||||
blog: Blog;
|
||||
}
|
||||
|
||||
export const BlogItem: React.FC<Props> = ({ blog }) => {
|
||||
return (
|
||||
<article className="blogitem md:grid md:grid-cols-4 md:items-baseline">
|
||||
<Card className="blogitem-card md:col-span-3">
|
||||
<Card.Title className="blogitem-title" href={`${blog.urlPath}`}>
|
||||
{blog.title}
|
||||
</Card.Title>
|
||||
<Card.Eyebrow
|
||||
as="time"
|
||||
dateTime={blog.date}
|
||||
className="blogitem-date md:hidden"
|
||||
decorate
|
||||
>
|
||||
{formatDate(blog.date)}
|
||||
</Card.Eyebrow>
|
||||
{blog.description && (
|
||||
<Card.Description className="blogitem-descr">
|
||||
{blog.description}
|
||||
</Card.Description>
|
||||
)}
|
||||
<Card.Cta className="blogitem-cta">Read article</Card.Cta>
|
||||
</Card>
|
||||
<Card.Eyebrow
|
||||
as="time"
|
||||
dateTime={blog.date}
|
||||
className="blogitem-date mt-1 hidden md:block"
|
||||
>
|
||||
{formatDate(blog.date)}
|
||||
</Card.Eyebrow>
|
||||
</article>
|
||||
);
|
||||
};
|
||||
36
packages/core/src/ui/Blog/BlogsList.tsx
Normal file
36
packages/core/src/ui/Blog/BlogsList.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { useState } from "react";
|
||||
import { BlogItem } from "./BlogItem";
|
||||
|
||||
const BLOGS_LOAD_COUNT = 10;
|
||||
|
||||
// TODO types
|
||||
export const BlogsList: React.FC<any> = ({ blogs }) => {
|
||||
const [blogsCount, setBlogsCount] = useState(BLOGS_LOAD_COUNT);
|
||||
|
||||
const handleLoadMore = () => {
|
||||
setBlogsCount((prevCount) => prevCount + BLOGS_LOAD_COUNT);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="md:border-l md:border-zinc-100 md:pl-6 md:dark:border-zinc-700/40">
|
||||
<div className="flex flex-col space-y-16">
|
||||
{blogs.slice(0, blogsCount).map((blog) => {
|
||||
return <BlogItem key={blog.urlPath} blog={blog} />;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
{blogs.length > blogsCount && (
|
||||
<div className="text-center pt-20">
|
||||
<button
|
||||
onClick={handleLoadMore}
|
||||
type="button"
|
||||
className="inline-flex items-center rounded border border-gray-300 px-2.5 py-1.5 text-xs font-medium text-gray-200 shadow-sm hover:bg-gray-50/10 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
>
|
||||
Show more
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
1
packages/core/src/ui/Blog/index.ts
Normal file
1
packages/core/src/ui/Blog/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { BlogsList } from "./BlogsList";
|
||||
38
packages/core/src/ui/BlogLayout/BlogLayout.tsx
Normal file
38
packages/core/src/ui/BlogLayout/BlogLayout.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
/* eslint import/no-default-export: off */
|
||||
import { formatDate } from "../../utils/formatDate";
|
||||
import { Avatar } from "../Avatar";
|
||||
|
||||
// TODO
|
||||
type Props = any;
|
||||
|
||||
export const BlogLayout: React.FC<Props> = ({ children, ...frontMatter }) => {
|
||||
const { title, date, authors } = frontMatter;
|
||||
|
||||
return (
|
||||
<article className="docs prose prose-a:text-primary dark:prose-a:text-primary-dark prose-strong:text-primary dark:prose-strong:text-primary-dark prose-code:text-primary dark:prose-code:text-primary-dark prose-headings:text-primary dark:prose-headings:text-primary-dark prose text-primary dark:text-primary-dark prose-headings:font-headings dark:prose-invert prose-a:break-words mx-auto p-6">
|
||||
<header>
|
||||
<div className="mb-4 flex-col items-center">
|
||||
{title && <h1 className="flex justify-center">{title}</h1>}
|
||||
{date && (
|
||||
<p className="text-sm text-zinc-400 dark:text-zinc-500 flex justify-center">
|
||||
<time dateTime={date}>{formatDate(date)}</time>
|
||||
</p>
|
||||
)}
|
||||
{authors && (
|
||||
<div className="flex flex-wrap not-prose items-center space-x-6 space-y-3 justify-center">
|
||||
{authors.map(({ name, avatar, urlPath }) => (
|
||||
<Avatar
|
||||
key={urlPath || name}
|
||||
name={name}
|
||||
img={avatar}
|
||||
href={urlPath ? `/${urlPath}` : undefined}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
<section>{children}</section>
|
||||
</article>
|
||||
);
|
||||
};
|
||||
1
packages/core/src/ui/BlogLayout/index.ts
Normal file
1
packages/core/src/ui/BlogLayout/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { BlogLayout } from "./BlogLayout";
|
||||
170
packages/core/src/ui/Card/Card.tsx
Normal file
170
packages/core/src/ui/Card/Card.tsx
Normal file
@@ -0,0 +1,170 @@
|
||||
// import Link from 'next/link'
|
||||
import clsx from "clsx";
|
||||
import { ChevronRightIcon } from "../Icons";
|
||||
|
||||
interface CardProps extends React.PropsWithChildren {
|
||||
as?: React.ElementType;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface CardLinkProps extends React.PropsWithChildren {
|
||||
href?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface CardTitleProps extends React.PropsWithChildren {
|
||||
as?: React.ElementType;
|
||||
href?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface CardDescriptionProps extends React.PropsWithChildren {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface CardCtaProps extends React.PropsWithChildren {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface CardEyebrowProps extends React.PropsWithChildren {
|
||||
as?: React.ElementType;
|
||||
decorate?: boolean;
|
||||
className?: string;
|
||||
[x: string]: unknown;
|
||||
}
|
||||
|
||||
type Card = React.FC<CardProps> & { Link: React.FC<CardLinkProps> } & {
|
||||
Title: React.FC<CardTitleProps>;
|
||||
} & { Description: React.FC<CardDescriptionProps> } & {
|
||||
Cta: React.FC<CardCtaProps>;
|
||||
} & { Eyebrow: React.FC<CardEyebrowProps> };
|
||||
|
||||
export const Card: Card = ({ children, as: Component = "div", className }) => {
|
||||
return (
|
||||
<Component
|
||||
className={clsx(className, "group relative flex flex-col items-start")}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
Card.Link = function CardLink({ children, href, className, ...props }) {
|
||||
// <Link {...props}>
|
||||
// <span className="absolute -inset-y-6 -inset-x-4 z-20 sm:-inset-x-6 sm:rounded-2xl" />
|
||||
// <span className="relative z-10">{children}</span>
|
||||
// </Link>
|
||||
return (
|
||||
<>
|
||||
<div className="absolute -inset-y-6 -inset-x-4 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 dark:bg-slate-800/75 sm:-inset-x-6 sm:rounded-2xl" />
|
||||
<a href={href} className={className} {...props}>
|
||||
<span className="absolute -inset-y-6 -inset-x-4 z-20 sm:-inset-x-6 sm:rounded-2xl" />
|
||||
<span className="relative z-10">{children}</span>
|
||||
</a>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Card.Title = function CardTitle({
|
||||
as: Component = "h2",
|
||||
href,
|
||||
children,
|
||||
className,
|
||||
}) {
|
||||
return (
|
||||
<Component
|
||||
className={clsx(
|
||||
className,
|
||||
"text-base font-semibold tracking-tight text-zinc-800 dark:text-zinc-100"
|
||||
)}
|
||||
>
|
||||
{href ? <Card.Link href={href}>{children}</Card.Link> : children}
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
Card.Description = function CardDescription({ children, className }) {
|
||||
return (
|
||||
<p
|
||||
className={clsx(
|
||||
className,
|
||||
"relative z-10 mt-2 text-sm text-zinc-600 dark:text-zinc-400"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
Card.Cta = function CardCta({ children, className }) {
|
||||
return (
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className={clsx(
|
||||
className,
|
||||
"relative z-10 mt-4 flex items-center text-sm font-medium text-secondary dark:text-secondary-dark"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
<ChevronRightIcon className="ml-1 h-4 w-4 stroke-current" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/* Card.Avatar = function CardAvatar({ name, src, href }) {
|
||||
* return (
|
||||
* <a href={href} className="group block flex-shrink-0 mt-2">
|
||||
* <div className="flex items-center">
|
||||
* <div>
|
||||
* {src ? (
|
||||
* <img
|
||||
* className="inline-block h-9 w-9 rounded-full"
|
||||
* src={src}
|
||||
* alt={name}
|
||||
* />
|
||||
* ) : (
|
||||
* <span className="inline-flex h-6 w-6 items-center justify-center rounded-full bg-gray-500">
|
||||
* <span className="text-xs font-medium leading-none text-white">
|
||||
* {initialsFromName(name)}
|
||||
* </span>
|
||||
* </span>
|
||||
* )}
|
||||
* </div>
|
||||
* <div className="ml-3">
|
||||
* <p className="text-sm font-medium text-gray-700 group-hover:text-gray-900">
|
||||
* {name}
|
||||
* </p>
|
||||
* </div>
|
||||
* </div>
|
||||
* </a>
|
||||
* );
|
||||
* }; */
|
||||
|
||||
Card.Eyebrow = function CardEyebrow({
|
||||
as: Component = "p",
|
||||
decorate = false,
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}) {
|
||||
return (
|
||||
<Component
|
||||
className={clsx(
|
||||
className,
|
||||
"relative z-10 order-first mb-3 flex items-center text-sm text-zinc-400 dark:text-zinc-500",
|
||||
decorate && "pl-3.5"
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{decorate && (
|
||||
<span
|
||||
className="absolute inset-y-0 left-0 flex items-center"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<span className="h-4 w-0.5 rounded-full bg-zinc-200 dark:bg-zinc-500" />
|
||||
</span>
|
||||
)}
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
1
packages/core/src/ui/Card/index.ts
Normal file
1
packages/core/src/ui/Card/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { Card } from "./Card";
|
||||
25
packages/core/src/ui/Comments/Disqus.tsx
Normal file
25
packages/core/src/ui/Comments/Disqus.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { DiscussionEmbed } from "disqus-react";
|
||||
|
||||
export interface DisqusConfig {
|
||||
provider: "disqus";
|
||||
pages?: Array<string>;
|
||||
config: {
|
||||
shortname: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type DisqusProps = DisqusConfig["config"] & {
|
||||
slug?: string;
|
||||
};
|
||||
|
||||
export const Disqus: React.FC<DisqusProps> = ({ shortname, slug }) => {
|
||||
return (
|
||||
<DiscussionEmbed
|
||||
shortname={shortname}
|
||||
config={{
|
||||
url: window?.location?.href,
|
||||
identifier: slug,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
53
packages/core/src/ui/Comments/Giscus.tsx
Normal file
53
packages/core/src/ui/Comments/Giscus.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import Giscus, { BooleanString, Mapping, Repo } from "@giscus/react";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
export interface GiscusConfig {
|
||||
provider: "giscus";
|
||||
pages?: Array<string>;
|
||||
config: {
|
||||
theme?: string;
|
||||
mapping: Mapping;
|
||||
repo: Repo;
|
||||
repositoryId: string;
|
||||
category: string;
|
||||
categoryId: string;
|
||||
reactions: BooleanString;
|
||||
metadata: BooleanString;
|
||||
inputPosition?: string;
|
||||
lang?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type GiscusProps = GiscusConfig["config"];
|
||||
|
||||
export const GiscusReactComponent: React.FC<GiscusProps> = ({
|
||||
repo,
|
||||
repositoryId,
|
||||
category,
|
||||
categoryId,
|
||||
reactions = "0",
|
||||
metadata = "0",
|
||||
mapping = "pathname",
|
||||
theme = "light",
|
||||
}) => {
|
||||
const { theme: nextTheme, resolvedTheme } = useTheme();
|
||||
const commentsTheme =
|
||||
nextTheme === "dark" || resolvedTheme === "dark"
|
||||
? "transparent_dark"
|
||||
: theme;
|
||||
|
||||
return (
|
||||
<Giscus
|
||||
repo={repo}
|
||||
repoId={repositoryId}
|
||||
category={category}
|
||||
categoryId={categoryId}
|
||||
mapping={mapping}
|
||||
inputPosition="top"
|
||||
reactionsEnabled={reactions}
|
||||
emitMetadata={metadata}
|
||||
// TODO: remove transparent_dark after theme toggle fix
|
||||
theme={nextTheme ? commentsTheme : "transparent_dark"}
|
||||
/>
|
||||
);
|
||||
};
|
||||
59
packages/core/src/ui/Comments/Utterances.tsx
Normal file
59
packages/core/src/ui/Comments/Utterances.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { useEffect, useCallback } from "react";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
export interface UtterancesConfig {
|
||||
provider: "utterances";
|
||||
pages?: Array<string>;
|
||||
config: {
|
||||
theme?: string;
|
||||
repo: string;
|
||||
label: string;
|
||||
issueTerm: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type UtterancesProps = UtterancesConfig["config"];
|
||||
|
||||
export const Utterances: React.FC<UtterancesProps> = ({
|
||||
repo,
|
||||
label = "comments",
|
||||
issueTerm = "pathname",
|
||||
theme = "github-light",
|
||||
}) => {
|
||||
const { theme: nextTheme, resolvedTheme } = useTheme();
|
||||
// TODO: remove preferred-color-scheme after theme toggle fix
|
||||
const commentsTheme = nextTheme
|
||||
? nextTheme === "dark" || resolvedTheme === "dark"
|
||||
? "github-dark"
|
||||
: theme
|
||||
: "preferred-color-scheme";
|
||||
|
||||
const COMMENTS_ID = "comments-container";
|
||||
|
||||
const LoadComments = useCallback(() => {
|
||||
const script = document.createElement("script");
|
||||
script.src = "https://utteranc.es/client.js";
|
||||
script.setAttribute("repo", repo);
|
||||
script.setAttribute("issue-term", issueTerm);
|
||||
script.setAttribute("label", label);
|
||||
script.setAttribute("theme", commentsTheme);
|
||||
script.setAttribute("crossorigin", "anonymous");
|
||||
script.async = true;
|
||||
|
||||
const comments = document.getElementById(COMMENTS_ID);
|
||||
if (comments) comments.appendChild(script);
|
||||
|
||||
return () => {
|
||||
const comments = document.getElementById(COMMENTS_ID);
|
||||
if (comments) comments.innerHTML = "";
|
||||
};
|
||||
}, [commentsTheme, issueTerm]);
|
||||
|
||||
// Reload on theme change
|
||||
useEffect(() => {
|
||||
LoadComments();
|
||||
}, [LoadComments]);
|
||||
|
||||
// Added `relative` to fix a weird bug with `utterances-frame` position
|
||||
return <div className="utterances-frame relative" id={COMMENTS_ID} />;
|
||||
};
|
||||
53
packages/core/src/ui/Comments/index.tsx
Normal file
53
packages/core/src/ui/Comments/index.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import dynamic from "next/dynamic.js";
|
||||
import { GiscusReactComponent, GiscusConfig, GiscusProps } from "./Giscus";
|
||||
import { Utterances, UtterancesConfig, UtterancesProps } from "./Utterances";
|
||||
import { Disqus, DisqusConfig, DisqusProps } from "./Disqus";
|
||||
|
||||
export type CommentsConfig = GiscusConfig | UtterancesConfig | DisqusConfig;
|
||||
|
||||
export interface CommentsProps {
|
||||
commentsConfig: CommentsConfig;
|
||||
slug?: string;
|
||||
}
|
||||
|
||||
const GiscusComponent = dynamic<GiscusProps>(
|
||||
() => {
|
||||
return import("./Giscus").then((mod) => mod.GiscusReactComponent);
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
const UtterancesComponent = dynamic<UtterancesProps>(
|
||||
() => {
|
||||
return import("./Utterances").then((mod) => mod.Utterances);
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
const DisqusComponent = dynamic<DisqusProps>(
|
||||
() => {
|
||||
return import("./Disqus").then((mod) => mod.Disqus);
|
||||
},
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
export const Comments = ({ commentsConfig, slug }: CommentsProps) => {
|
||||
switch (commentsConfig.provider) {
|
||||
case "giscus":
|
||||
return <GiscusComponent {...commentsConfig.config} />;
|
||||
case "utterances":
|
||||
return <UtterancesComponent {...commentsConfig.config} />;
|
||||
case "disqus":
|
||||
return <DisqusComponent slug={slug} {...commentsConfig.config} />;
|
||||
}
|
||||
};
|
||||
|
||||
export { GiscusReactComponent, Utterances, Disqus };
|
||||
export type {
|
||||
GiscusConfig,
|
||||
GiscusProps,
|
||||
UtterancesConfig,
|
||||
UtterancesProps,
|
||||
DisqusConfig,
|
||||
DisqusProps,
|
||||
};
|
||||
22
packages/core/src/ui/DocsLayout/Docs.tsx
Normal file
22
packages/core/src/ui/DocsLayout/Docs.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
/* eslint import/no-default-export: off */
|
||||
import { formatDate } from "../../utils/formatDate";
|
||||
|
||||
// TODO types
|
||||
export const DocsLayout: React.FC<any> = ({ children, ...frontMatter }) => {
|
||||
const { title, created } = frontMatter;
|
||||
return (
|
||||
<article className="docs prose prose-a:text-primary dark:prose-a:text-primary-dark prose-strong:text-primary dark:prose-strong:text-primary-dark prose-code:text-primary dark:prose-code:text-primary-dark prose-headings:text-primary dark:prose-headings:text-primary-dark prose text-primary dark:text-primary-dark dark:prose-invert prose-headings:font-headings prose-a:break-words mx-auto">
|
||||
<header>
|
||||
<div className="mb-6">
|
||||
{created && (
|
||||
<p className="text-sm text-zinc-400 dark:text-zinc-500">
|
||||
<time dateTime={created}>{formatDate(created)}</time>
|
||||
</p>
|
||||
)}
|
||||
{title && <h1>{title}</h1>}
|
||||
</div>
|
||||
</header>
|
||||
<section>{children}</section>
|
||||
</article>
|
||||
);
|
||||
};
|
||||
1
packages/core/src/ui/DocsLayout/index.ts
Normal file
1
packages/core/src/ui/DocsLayout/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { DocsLayout } from "./Docs";
|
||||
90
packages/core/src/ui/Hero/Hero.tsx
Normal file
90
packages/core/src/ui/Hero/Hero.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
interface Button {
|
||||
title: string;
|
||||
href: string;
|
||||
type: 'filled' | 'text'
|
||||
}
|
||||
|
||||
export interface HeroProps {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
announcement?: {
|
||||
title: string;
|
||||
href?: string;
|
||||
};
|
||||
buttons?: Array<Button>
|
||||
}
|
||||
|
||||
const buttonStyle = {
|
||||
'filled': "rounded-md bg-secondary px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-secondary/90 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
|
||||
'text': "text-sm font-semibold leading-6"
|
||||
}
|
||||
|
||||
|
||||
export const Hero: React.FC<HeroProps> = ({ title, subtitle, announcement, buttons }) => {
|
||||
|
||||
return (
|
||||
<div className="text-primary dark:text-primary-dark">
|
||||
<div className="relative isolate px-6 pt-14 lg:px-8">
|
||||
{/* <div
|
||||
className="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div
|
||||
className="relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#38bdf8] to-[#89a8fc] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]"
|
||||
style={{
|
||||
clipPath:
|
||||
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
|
||||
}}
|
||||
/>
|
||||
</div> */}
|
||||
<div className="mx-auto max-w-2xl py-16 sm:py-32 lg:py-40">
|
||||
{announcement && (
|
||||
<div className="hidden sm:mb-8 sm:flex sm:justify-center">
|
||||
<div className="relative rounded-full px-3 py-1 text-sm leading-6 ring-1 ring-primary/20 hover:ring-primary/30 dark:ring-primary-dark/30 dark:hover:ring-primary-dark/40">
|
||||
{announcement.title}{' '}
|
||||
<a href="#" className="font-semibold text-secondary">
|
||||
<span className="absolute inset-0" aria-hidden="true" />
|
||||
Read more <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold tracking-tight sm:text-6xl">
|
||||
{title}
|
||||
</h1>
|
||||
{subtitle && (
|
||||
<p className="mt-6 text-lg leading-8 text-primary/90 dark:text-primary-dark/80">
|
||||
{subtitle}
|
||||
</p>
|
||||
)}
|
||||
{buttons && buttons.length && (
|
||||
<div className="mt-10 flex items-center justify-center gap-x-6">
|
||||
{buttons.map((b) => (
|
||||
<a
|
||||
href={b.href}
|
||||
className={buttonStyle[b.type]}
|
||||
>
|
||||
{b.title}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* <div
|
||||
className="absolute inset-x-0 top-[calc(100%-13rem)] -z-10 transform-gpu overflow-hidden blur-3xl sm:top-[calc(100%-30rem)]"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div
|
||||
className="relative left-[calc(50%+3rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 bg-gradient-to-tr from-[#89a8fc] to-[#38bdf8] opacity-30 sm:left-[calc(50%+36rem)] sm:w-[72.1875rem]"
|
||||
style={{
|
||||
clipPath:
|
||||
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
|
||||
}}
|
||||
/>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
1
packages/core/src/ui/Hero/index.ts
Normal file
1
packages/core/src/ui/Hero/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { Hero } from "./Hero"
|
||||
12
packages/core/src/ui/Icons/ChevronRightIcon.tsx
Normal file
12
packages/core/src/ui/Icons/ChevronRightIcon.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
export const ChevronRightIcon: React.FC<{ [x: string]: unknown }> = (props) => {
|
||||
return (
|
||||
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true" {...props}>
|
||||
<path
|
||||
d="M6.75 5.75 9.25 8l-2.5 2.25"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
14
packages/core/src/ui/Icons/CloseIcon.tsx
Normal file
14
packages/core/src/ui/Icons/CloseIcon.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
export const CloseIcon: React.FC<{ [x: string]: unknown }> = (props) => {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
{...props}
|
||||
>
|
||||
<path d="M5 5l14 14M19 5l-14 14" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
14
packages/core/src/ui/Icons/DiscordIcon.tsx
Normal file
14
packages/core/src/ui/Icons/DiscordIcon.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
export const DiscordIcon: React.FC<{ [x: string]: unknown }> = (props) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
{...props}
|
||||
>
|
||||
<path d="M13.545 2.907a13.227 13.227 0 0 0-3.257-1.011.05.05 0 0 0-.052.025c-.141.25-.297.577-.406.833a12.19 12.19 0 0 0-3.658 0 8.258 8.258 0 0 0-.412-.833.051.051 0 0 0-.052-.025c-1.125.194-2.22.534-3.257 1.011a.041.041 0 0 0-.021.018C.356 6.024-.213 9.047.066 12.032c.001.014.01.028.021.037a13.276 13.276 0 0 0 3.995 2.02.05.05 0 0 0 .056-.019c.308-.42.582-.863.818-1.329a.05.05 0 0 0-.01-.059.051.051 0 0 0-.018-.011 8.875 8.875 0 0 1-1.248-.595.05.05 0 0 1-.02-.066.051.051 0 0 1 .015-.019c.084-.063.168-.129.248-.195a.05.05 0 0 1 .051-.007c2.619 1.196 5.454 1.196 8.041 0a.052.052 0 0 1 .053.007c.08.066.164.132.248.195a.051.051 0 0 1-.004.085 8.254 8.254 0 0 1-1.249.594.05.05 0 0 0-.03.03.052.052 0 0 0 .003.041c.24.465.515.909.817 1.329a.05.05 0 0 0 .056.019 13.235 13.235 0 0 0 4.001-2.02.049.049 0 0 0 .021-.037c.334-3.451-.559-6.449-2.366-9.106a.034.034 0 0 0-.02-.019Zm-8.198 7.307c-.789 0-1.438-.724-1.438-1.612 0-.889.637-1.613 1.438-1.613.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612Zm5.316 0c-.788 0-1.438-.724-1.438-1.612 0-.889.637-1.613 1.438-1.613.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
7
packages/core/src/ui/Icons/GitHubIcon.tsx
Normal file
7
packages/core/src/ui/Icons/GitHubIcon.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
export const GitHubIcon: React.FC<{ [x: string]: unknown }> = (props) => {
|
||||
return (
|
||||
<svg aria-hidden="true" viewBox="0 0 16 16" {...props}>
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
14
packages/core/src/ui/Icons/MenuIcon.tsx
Normal file
14
packages/core/src/ui/Icons/MenuIcon.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
export const MenuIcon: React.FC<{ [x: string]: unknown }> = (props) => {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
{...props}
|
||||
>
|
||||
<path d="M4 7h16M4 12h16M4 17h16" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
7
packages/core/src/ui/Icons/SearchIcon.tsx
Normal file
7
packages/core/src/ui/Icons/SearchIcon.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
export const SearchIcon: React.FC<{ [x: string]: unknown }> = (props) => {
|
||||
return (
|
||||
<svg aria-hidden="true" viewBox="0 0 20 20" {...props}>
|
||||
<path d="M16.293 17.707a1 1 0 0 0 1.414-1.414l-1.414 1.414ZM9 14a5 5 0 0 1-5-5H2a7 7 0 0 0 7 7v-2ZM4 9a5 5 0 0 1 5-5V2a7 7 0 0 0-7 7h2Zm5-5a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7v2Zm8.707 12.293-3.757-3.757-1.414 1.414 3.757 3.757 1.414-1.414ZM14 9a4.98 4.98 0 0 1-1.464 3.536l1.414 1.414A6.98 6.98 0 0 0 16 9h-2Zm-1.464 3.536A4.98 4.98 0 0 1 9 14v2a6.98 6.98 0 0 0 4.95-2.05l-1.414-1.414Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
6
packages/core/src/ui/Icons/index.tsx
Normal file
6
packages/core/src/ui/Icons/index.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
export { GitHubIcon } from "./GitHubIcon";
|
||||
export { DiscordIcon } from "./DiscordIcon";
|
||||
export { MenuIcon } from "./MenuIcon";
|
||||
export { CloseIcon } from "./CloseIcon";
|
||||
export { SearchIcon } from "./SearchIcon";
|
||||
export { ChevronRightIcon } from "./ChevronRightIcon";
|
||||
30
packages/core/src/ui/Layout/EditThisPage.tsx
Normal file
30
packages/core/src/ui/Layout/EditThisPage.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
export const EditThisPage = ({ url }: { url: string }) => {
|
||||
return (
|
||||
<div className="mb-10 prose dark:prose-invert p-6 mx-auto">
|
||||
<a
|
||||
className="flex no-underline font-semibold justify-center"
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Edit this page
|
||||
<span className="mx-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
61
packages/core/src/ui/Layout/Footer.tsx
Normal file
61
packages/core/src/ui/Layout/Footer.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import Link from "next/link.js";
|
||||
|
||||
import { AuthorConfig, NavLink } from "../types";
|
||||
|
||||
interface Props {
|
||||
links: Array<NavLink>;
|
||||
author: AuthorConfig;
|
||||
}
|
||||
|
||||
export const Footer: React.FC<Props> = ({ links, author }) => {
|
||||
return (
|
||||
<footer className="bg-background dark:bg-background-dark prose dark:prose-invert max-w-none flex flex-col items-center justify-center w-full h-auto pt-10 pb-20">
|
||||
<div className="flex w-full flex-wrap justify-center">
|
||||
{links.map((item) => (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
className="inline-flex items-center mx-4 px-1 pt-1 font-regular hover:text-slate-300 no-underline"
|
||||
>
|
||||
{/* TODO aria-current={item.current ? "page" : undefined} */}
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<p className="flex items-center justify-center">
|
||||
Created by
|
||||
<a
|
||||
href={author.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center no-underline"
|
||||
>
|
||||
{author.logo && (
|
||||
<img
|
||||
src={author.logo}
|
||||
alt={author.name}
|
||||
className="my-0 mx-1 h-6 block"
|
||||
/>
|
||||
)}
|
||||
{author.name}
|
||||
</a>
|
||||
</p>
|
||||
<p className="flex items-center justify-center">
|
||||
Made with
|
||||
<a
|
||||
href="https://flowershow.app/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center no-underline"
|
||||
>
|
||||
<img
|
||||
src="https://flowershow.app/images/logo.svg"
|
||||
alt="Flowershow"
|
||||
className="my-0 mx-1 h-6 block"
|
||||
/>
|
||||
Flowershow
|
||||
</a>
|
||||
</p>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
147
packages/core/src/ui/Layout/Layout.tsx
Normal file
147
packages/core/src/ui/Layout/Layout.tsx
Normal file
@@ -0,0 +1,147 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import Head from "next/head.js";
|
||||
import { NextRouter, useRouter } from "next/router.js";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { useTableOfContents } from "./useTableOfContents";
|
||||
import { collectHeadings } from "../../utils";
|
||||
|
||||
import { Nav } from "../Nav";
|
||||
import { SiteToc, NavItem, NavGroup } from "../SiteToc";
|
||||
import { Comments, CommentsConfig } from "../Comments";
|
||||
import { Footer } from "./Footer";
|
||||
import { EditThisPage } from "./EditThisPage";
|
||||
import { TableOfContents, TocSection } from "./TableOfContents";
|
||||
import { NavConfig, ThemeConfig } from "../Nav";
|
||||
import { AuthorConfig } from "../types";
|
||||
|
||||
interface Props extends React.PropsWithChildren {
|
||||
showComments: boolean;
|
||||
showEditLink: boolean;
|
||||
showSidebar: boolean;
|
||||
showToc: boolean;
|
||||
nav: NavConfig;
|
||||
author: AuthorConfig;
|
||||
theme: ThemeConfig;
|
||||
urlPath: string;
|
||||
commentsConfig: CommentsConfig;
|
||||
siteMap: Array<NavItem | NavGroup>;
|
||||
editUrl?: string;
|
||||
}
|
||||
|
||||
export const Layout: React.FC<Props> = ({
|
||||
children,
|
||||
nav,
|
||||
author,
|
||||
theme,
|
||||
showEditLink,
|
||||
showToc,
|
||||
showSidebar,
|
||||
urlPath,
|
||||
showComments,
|
||||
commentsConfig,
|
||||
editUrl,
|
||||
siteMap,
|
||||
}) => {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [tableOfContents, setTableOfContents] = useState<TocSection[]>([]);
|
||||
const currentSection = useTableOfContents(tableOfContents);
|
||||
const router: NextRouter = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (!showToc) return;
|
||||
const headingNodes: NodeListOf<HTMLHeadingElement> =
|
||||
document.querySelectorAll("h1,h2,h3");
|
||||
const toc = collectHeadings(headingNodes);
|
||||
setTableOfContents(toc ?? []);
|
||||
}, [router.asPath, showToc]); // update table of contents on route change with next/link
|
||||
|
||||
useEffect(() => {
|
||||
function onScroll() {
|
||||
setIsScrolled(window.scrollY > 0);
|
||||
}
|
||||
onScroll();
|
||||
window.addEventListener("scroll", onScroll, { passive: true });
|
||||
return () => {
|
||||
window.removeEventListener("scroll", onScroll);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>💐</text></svg>"
|
||||
/>
|
||||
<meta charSet="utf-8" />
|
||||
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
|
||||
</Head>
|
||||
<div className="min-h-screen bg-background dark:bg-background-dark">
|
||||
{/* NAVBAR */}
|
||||
<div
|
||||
className={clsx(
|
||||
"sticky top-0 z-50 w-full",
|
||||
isScrolled
|
||||
? "dark:bg-background-dark/95 bg-background/95 backdrop-blur [@supports(backdrop-filter:blur(0))]:dark:bg-background-dark/75"
|
||||
: "dark:bg-background-dark bg-background"
|
||||
)}
|
||||
>
|
||||
<div className="max-w-8xl mx-auto p-4 md:px-8">
|
||||
<Nav
|
||||
title={nav.title}
|
||||
logo={nav.logo}
|
||||
links={nav.links}
|
||||
search={nav.search}
|
||||
social={nav.social}
|
||||
defaultTheme={theme.defaultTheme}
|
||||
themeToggleIcon={theme.themeToggleIcon}
|
||||
>
|
||||
{showSidebar && <SiteToc currentPath={urlPath} nav={siteMap} />}
|
||||
</Nav>
|
||||
</div>
|
||||
</div>
|
||||
{/* wrapper for sidebar, main content and ToC */}
|
||||
<div
|
||||
className={clsx(
|
||||
"max-w-8xl mx-auto px-4 md:px-8",
|
||||
showSidebar && "lg:ml-[18rem]",
|
||||
showToc && "xl:mr-[18rem]"
|
||||
)}
|
||||
>
|
||||
{/* SIDEBAR */}
|
||||
{showSidebar && (
|
||||
<div className="hidden lg:block fixed z-20 w-[18rem] top-[4.6rem] right-auto bottom-0 left-[max(0px,calc(50%-44rem))] pt-8 pl-8 overflow-y-auto">
|
||||
<SiteToc currentPath={urlPath} nav={siteMap} />
|
||||
</div>
|
||||
)}
|
||||
{/* MAIN CONTENT & FOOTER */}
|
||||
<main className="mx-auto pt-8">
|
||||
{children}
|
||||
{/* EDIT THIS PAGE LINK */}
|
||||
{showEditLink && editUrl && <EditThisPage url={editUrl} />}
|
||||
{/* PAGE COMMENTS */}
|
||||
{showComments && (
|
||||
<div
|
||||
className="prose mx-auto pt-6 pb-6 text-center text-gray-700 dark:text-gray-300"
|
||||
id="comment"
|
||||
>
|
||||
{<Comments commentsConfig={commentsConfig} slug={urlPath} />}
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
<Footer links={nav.links} author={author} />
|
||||
{/** TABLE OF CONTENTS */}
|
||||
{showToc && tableOfContents.length > 0 && (
|
||||
<div className="hidden xl:block fixed z-20 w-[18rem] top-[4.6rem] bottom-0 right-[max(0px,calc(50%-44rem))] left-auto pt-8 pr-8 overflow-y-auto">
|
||||
<TableOfContents
|
||||
tableOfContents={tableOfContents}
|
||||
currentSection={currentSection}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
90
packages/core/src/ui/Layout/TableOfContents.tsx
Normal file
90
packages/core/src/ui/Layout/TableOfContents.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import Link from "next/link.js";
|
||||
|
||||
export interface TocSection {
|
||||
id: string;
|
||||
title: string;
|
||||
level: string;
|
||||
children?: any;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
tableOfContents: TocSection[];
|
||||
currentSection: string;
|
||||
}
|
||||
|
||||
export const TableOfContents: React.FC<Props> = ({
|
||||
tableOfContents,
|
||||
currentSection,
|
||||
}) => {
|
||||
function isActiveSection(section) {
|
||||
if (section.id === currentSection) {
|
||||
return true;
|
||||
}
|
||||
if (!section.children) {
|
||||
return false;
|
||||
}
|
||||
return section.children.findIndex(isActiveSection) > -1;
|
||||
}
|
||||
|
||||
return (
|
||||
<nav aria-labelledby="on-this-page-title">
|
||||
<h2 className="font-display text-md font-medium text-slate-900 dark:text-white">
|
||||
On this page
|
||||
</h2>
|
||||
<ol className="mt-4 space-y-3 text-sm">
|
||||
{tableOfContents.map((section) => (
|
||||
<li key={section.id}>
|
||||
<h3>
|
||||
<Link
|
||||
href={`#${section.id}`}
|
||||
className={
|
||||
isActiveSection(section)
|
||||
? "text-secondary dark:text-secondary-dark"
|
||||
: "font-normal text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-300"
|
||||
}
|
||||
>
|
||||
{section.title}
|
||||
</Link>
|
||||
</h3>
|
||||
{section.children && section.children.length > 0 && (
|
||||
<ol className="mt-2 space-y-3 pl-5 text-slate-500 dark:text-slate-400">
|
||||
{section.children.map((subSection) => (
|
||||
<li key={subSection.id}>
|
||||
<Link
|
||||
href={`#${subSection.id}`}
|
||||
className={
|
||||
isActiveSection(subSection)
|
||||
? "text-secondary dark:text-secondary-dark"
|
||||
: "hover:text-slate-600 dark:hover:text-slate-300"
|
||||
}
|
||||
>
|
||||
{subSection.title}
|
||||
</Link>
|
||||
{subSection.children && subSection.children.length > 0 && (
|
||||
<ol className="mt-2 space-y-3 pl-5 text-slate-500 dark:text-slate-400">
|
||||
{subSection.children.map((thirdSection) => (
|
||||
<li key={thirdSection.id}>
|
||||
<Link
|
||||
href={`#${thirdSection.id}`}
|
||||
className={
|
||||
isActiveSection(thirdSection)
|
||||
? "text-secondary dark:text-secondary-dark"
|
||||
: "hover:text-slate-600 dark:hover:text-slate-300"
|
||||
}
|
||||
>
|
||||
{thirdSection.title}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user