├── .editorconfig ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .npmrc ├── .prettierrc ├── .yarnrc ├── LICENSE ├── README.md ├── demo ├── .gitignore ├── CHANGELOG.md ├── content │ ├── examples │ │ ├── comment-system.md │ │ ├── mdx-components │ │ │ └── FakeClock.tsx │ │ ├── mdx.mdx │ │ ├── override-styles.md │ │ └── syntax-highlight.md │ ├── features │ │ ├── graph-view.md │ │ ├── table-of-contents.md │ │ ├── using-frontmatter.md │ │ └── wiki-links.md │ ├── readme.md │ ├── showcase.md │ └── todo.md ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-ssr.js ├── package.json └── src │ ├── gatsby-theme-kb │ └── components │ │ └── Topic │ │ ├── Comment │ │ └── index.tsx │ │ └── index.tsx │ └── styles │ ├── main.css │ └── prism-theme.css ├── lerna.json ├── package.json ├── packages ├── gatsby-remark-wiki-link │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── gatsby-theme-kb │ ├── .gitignore │ ├── .prettierignore │ ├── .yarnrc │ ├── CHANGELOG.md │ ├── README.md │ ├── fragments.js │ ├── gatsby-browser.js │ ├── gatsby-config.js │ ├── gatsby-node-utils │ │ ├── makeSearchPlugins.js │ │ ├── shouldHandleFile.js │ │ └── source-nodes.js │ ├── gatsby-node.js │ ├── gatsby-ssr.js │ ├── package.json │ ├── postcss.config.js │ ├── src │ │ ├── components │ │ │ ├── DarkModeToggle │ │ │ │ ├── dark-mode-toggle.css │ │ │ │ └── index.tsx │ │ │ ├── GraphButton │ │ │ │ ├── graph-button.css │ │ │ │ └── index.tsx │ │ │ ├── GraphView │ │ │ │ ├── graph-view.css │ │ │ │ └── index.tsx │ │ │ ├── InlineTOC │ │ │ │ ├── index.tsx │ │ │ │ └── inline-toc.css │ │ │ ├── LinkReference │ │ │ │ ├── index.tsx │ │ │ │ └── link-reference.css │ │ │ ├── Search │ │ │ │ ├── index.tsx │ │ │ │ └── search.css │ │ │ ├── SiteSidebar │ │ │ │ ├── index.tsx │ │ │ │ └── site-sidebar.css │ │ │ ├── Topic │ │ │ │ ├── index.tsx │ │ │ │ └── topic.css │ │ │ ├── TopicLayout │ │ │ │ ├── index.tsx │ │ │ │ └── topic-layout.css │ │ │ ├── TreeView │ │ │ │ ├── index.tsx │ │ │ │ └── tree-view.css │ │ │ ├── header.css │ │ │ ├── header.js │ │ │ ├── icons │ │ │ │ ├── index.tsx │ │ │ │ └── svg-icon.css │ │ │ ├── layout.css │ │ │ ├── layout.js │ │ │ ├── mdx-components │ │ │ │ ├── AnchorTag.tsx │ │ │ │ ├── MDXRenderer.tsx │ │ │ │ ├── anchor-tag.css │ │ │ │ └── header-components.tsx │ │ │ └── seo.js │ │ ├── configs │ │ │ └── hotkeys.ts │ │ ├── env.ts │ │ ├── images │ │ │ ├── gatsby-astronaut.png │ │ │ └── gatsby-icon.png │ │ ├── pages │ │ │ └── 404.js │ │ ├── styles │ │ │ ├── base.css │ │ │ ├── components │ │ │ │ ├── link.css │ │ │ │ └── scrollbar.css │ │ │ ├── global.css │ │ │ ├── theme.css │ │ │ ├── tocbot.css │ │ │ └── vars.css │ │ ├── templates │ │ │ └── Topic.js │ │ ├── type.ts │ │ ├── use-graph-data.ts │ │ ├── use-search.tsx │ │ ├── use-window-size.ts │ │ └── utils │ │ │ ├── index.ts │ │ │ └── toc.ts │ ├── tailwind.config.js │ └── tsconfig.json └── transformer-wiki-references │ ├── CHANGELOG.md │ ├── README.md │ ├── __tests__ │ ├── get-references.spec.ts │ └── markdown-utils.spec.ts │ ├── gatsby-node.js │ ├── jest.config.js │ ├── package.json │ ├── src │ ├── cache.ts │ ├── compute-inbounds.ts │ ├── content-tree.ts │ ├── get-references.ts │ ├── index.ts │ ├── markdown-utils.ts │ ├── on-create-node.ts │ ├── on-pre-bootstrap.ts │ ├── options.ts │ ├── schema-customization.ts │ ├── type.ts │ └── util.ts │ └── tsconfig.json ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | max_line_length = 100 12 | quote_type = single 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: 'Build gatsby-project-kb site' 2 | 3 | on: 4 | push: 5 | branches: 6 | # - master 7 | - ci 8 | - feature/deploy 9 | 10 | jobs: 11 | build: 12 | name: Build Site 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@master 16 | - uses: actions/setup-node@v2 17 | with: 18 | node-version: "14" 19 | - name: yarn install 20 | uses: jaid/action-npm-install@v1.2.1 21 | - name: build 22 | uses: CultureHQ/actions-yarn@master 23 | env: 24 | KB_BASE_PATH: '/gatsby-project-kb' 25 | with: 26 | args: build 27 | - name: Deploy to GitHub Pages 28 | if: success() 29 | uses: crazy-max/ghaction-github-pages@v2 30 | with: 31 | target_branch: gh-pages 32 | build_dir: demo/public 33 | env: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | node_modules 4 | dist 5 | 6 | .cache/ 7 | 8 | node_modules 9 | package-lock.json 10 | yarn.lock 11 | !/yarn.lock 12 | 13 | .yalc 14 | yalc.lock 15 | 16 | packages/*/lib 17 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "singleQuote": true, 4 | "semi": false, 5 | "arrowParens": "always" 6 | } 7 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | registry https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) hikerpig, 2021. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gatsby-project-kb 2 | === 3 | 4 | Here is a project developing a gatsby theme for publishing **K**nowledge **B**ase. 5 | 6 | You can check out the demo and [documentation](https://gatsby-project-kb.vercel.app/). 7 | 8 | If you are looking for `gatsby-theme-kb`, go to directory [packages/gatsby-theme-kb](https://github.com/hikerpig/gatsby-project-kb/tree/master/packages/gatsby-theme-kb) for more detailed docs. 9 | 10 | ![](https://i.loli.net/2021/01/28/cD6QRIZqUoum4Tf.png) 11 | 12 | # Development 13 | 14 | File structure: 15 | 16 | ``` 17 | ├── demo // the demo site's code 18 | ├── packages 19 | └── gatsby-theme-kb // the Gatsby theme 20 | ├── yarn.lock 21 | ``` 22 | 23 | This is a common structure for developing Gatsby theme using yarn workspace. You can check more on Gatsby official tutorial [Building a Theme](https://www.gatsbyjs.com/tutorial/building-a-theme/). 24 | 25 | ## Run it locally 26 | 27 | ``` 28 | yarn # install dependencies 29 | yarn dev # start devlopment 30 | ``` 31 | 32 | # Support 33 | 34 | Feel free to open issues if you have any problems or suggestions for this project, I will do my best to solve them in my spare time. 35 | 36 | If you find it useful and find yourself in a mood of sunshine, you may support me a little pack of coffee beans. 37 | 38 | I like [Geisha](https://www.wikiwand.com/en/Geisha_\(coffee\)), you will like it, too. 39 | 40 | Buy Me A Coffee 41 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | public/ 2 | -------------------------------------------------------------------------------- /demo/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [1.4.5](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.4.4...demo@1.4.5) (2022-03-26) 7 | 8 | **Note:** Version bump only for package demo 9 | 10 | 11 | 12 | 13 | 14 | ## [1.4.3](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.4.2...demo@1.4.3) (2022-03-20) 15 | 16 | **Note:** Version bump only for package demo 17 | 18 | 19 | 20 | 21 | 22 | ## [1.4.2](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.4.2-alpha.1...demo@1.4.2) (2022-02-06) 23 | 24 | **Note:** Version bump only for package demo 25 | 26 | 27 | 28 | 29 | 30 | # [1.4.0](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.3.8...demo@1.4.0) (2021-10-24) 31 | 32 | 33 | ### Features 34 | 35 | * **demo:** an example of shadowing by adding a comment, close [#24](https://github.com/hikerpig/gatsby-project-kb/issues/24) ([5628ccf](https://github.com/hikerpig/gatsby-project-kb/commit/5628ccf2c0f57b2621398b0e82b7efefba05e065)) 36 | 37 | 38 | 39 | 40 | 41 | # [1.3.0-alpha.3](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.3.0-alpha.2...demo@1.3.0-alpha.3) (2021-04-28) 42 | 43 | **Note:** Version bump only for package demo 44 | 45 | 46 | 47 | 48 | 49 | # [1.3.0-alpha.2](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.3.0-alpha.1...demo@1.3.0-alpha.2) (2021-04-19) 50 | 51 | **Note:** Version bump only for package demo 52 | 53 | 54 | 55 | 56 | 57 | # [1.3.0-alpha.1](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.3.0-alpha.0...demo@1.3.0-alpha.1) (2021-04-07) 58 | 59 | **Note:** Version bump only for package demo 60 | 61 | 62 | 63 | 64 | 65 | # [1.3.0-alpha.0](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.2.4...demo@1.3.0-alpha.0) (2021-04-02) 66 | 67 | 68 | ### Features 69 | 70 | * Add anchor reference support, related [#8](https://github.com/hikerpig/gatsby-project-kb/issues/8) ([3c0d13a](https://github.com/hikerpig/gatsby-project-kb/commit/3c0d13a78146dc9b6bf1215af367fbd1e3a999d4)) 71 | * better wiki references resolving with `contentPath` option ([46b66a9](https://github.com/hikerpig/gatsby-project-kb/commit/46b66a973bbdd702dfadb523e9ab0ab91ed1d417)) 72 | 73 | 74 | 75 | 76 | 77 | ## [1.2.4-alpha.0](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.2.3...demo@1.2.4-alpha.0) (2021-03-04) 78 | 79 | **Note:** Version bump only for package demo 80 | 81 | 82 | 83 | 84 | 85 | ## [1.2.3](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.2.2...demo@1.2.3) (2021-03-03) 86 | 87 | **Note:** Version bump only for package demo 88 | 89 | 90 | 91 | 92 | 93 | ## [1.2.2](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.2.1...demo@1.2.2) (2021-02-28) 94 | 95 | 96 | ### Bug Fixes 97 | 98 | * **gatsby-theme-kb:** errors when rendering custom components in mdx mentioned in [#6](https://github.com/hikerpig/gatsby-project-kb/issues/6) ([006b87c](https://github.com/hikerpig/gatsby-project-kb/commit/006b87c3372908ae09f73bb9476171dfef279e05)) 99 | 100 | 101 | 102 | 103 | 104 | ## [1.2.1](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.2.0...demo@1.2.1) (2021-02-26) 105 | 106 | 107 | ### Bug Fixes 108 | 109 | * **gatsby-theme-kb:** graph view error due to lazy render ([fea20ff](https://github.com/hikerpig/gatsby-project-kb/commit/fea20ffbb4262e36d5adf707159f13c088d8842c)) 110 | 111 | 112 | 113 | 114 | 115 | # [1.2.0](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.1.3...demo@1.2.0) (2021-02-20) 116 | 117 | 118 | ### Features 119 | 120 | * add search in graph view and make it interactively highlighting result nodes ([0323db9](https://github.com/hikerpig/gatsby-project-kb/commit/0323db9ca8f8169d001b021724ca49714b5f10e4)) 121 | 122 | 123 | 124 | 125 | 126 | ## [1.1.3](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.1.2...demo@1.1.3) (2021-02-15) 127 | 128 | **Note:** Version bump only for package demo 129 | 130 | 131 | 132 | 133 | 134 | ## [1.1.2](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.1.1...demo@1.1.2) (2021-02-14) 135 | 136 | **Note:** Version bump only for package demo 137 | 138 | 139 | 140 | 141 | 142 | ## [1.1.1](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.1.0...demo@1.1.1) (2021-02-14) 143 | 144 | 145 | ### Bug Fixes 146 | 147 | * **gatsby-theme-kb:** misfunction in AnchorTag caused by v0.3.0 ([7739b49](https://github.com/hikerpig/gatsby-project-kb/commit/7739b496866eb6573dad0600fa252cd292aa1348)) 148 | 149 | 150 | 151 | 152 | 153 | # [1.1.0](https://github.com/hikerpig/gatsby-project-kb/compare/demo@1.0.3...demo@1.1.0) (2021-02-13) 154 | 155 | 156 | ### Features 157 | 158 | * **gatsby-theme-kb:** show backlink context, related [#1](https://github.com/hikerpig/gatsby-project-kb/issues/1) ([685b92c](https://github.com/hikerpig/gatsby-project-kb/commit/685b92c3970116cc593581f52ecc6e0b66b0c146)) 159 | -------------------------------------------------------------------------------- /demo/content/examples/comment-system.md: -------------------------------------------------------------------------------- 1 | Add a comment system 2 | === 3 | 4 | The `gatsby-theme-kb` itself **does not** have a comment system. 5 | 6 | But sure, you can see the comments in this demo. 7 | 8 | Here is an example of adding a comment system to your site using Gatsby's Shadowing feature. 9 | 10 | > 📢 Please read the doc [_Shadowing in Gatsby Themes_](https://www.gatsbyjs.com/docs/how-to/plugins-and-themes/shadowing/) first to have a basic understanding of shadowing. 11 | 12 | You can check the [demo code on Github](https://github.com/hikerpig/gatsby-project-kb/blob/master/demo/src/gatsby-theme-kb/components/Topic). 13 | 14 | ## Shadowing component 15 | 16 | Take this demo site for example, we add a component in our own site's source to shadow one in the `gatsby-theme-kb` without touching its code. 17 | 18 | Here is a simplified list of `gatsby-theme-kb/src/components` directory. Technically you can shadow any component, but we will focus on the `Topic` component for now as it is the main content of the page and very fit to hold the comments. 19 | 20 | For all the files those are capable of being shadowed in the `gatsby-theme-kb`, please [refer to its source code](https://github.com/hikerpig/gatsby-project-kb/tree/master/packages/gatsby-theme-kb/src). 21 | 22 | ``` text 23 | components 24 | ├── DarkModeToggle 25 | ├── GraphButton 26 | ├── GraphView 27 | ├── LinkReference 28 | ├── Search 29 | ├── SiteSidebar // topic left sidebar 30 | ├── Topic // topic main content 31 | ├── TopicLayout 32 | ├── TreeView // directory tree view inside the sidebar 33 | ├── mdx-components 34 | └── seo.js 35 | ``` 36 | 37 | - We can reuse the shadowed component by importing it from `gatsby-theme-kb/src/components/Topic`. 38 | - Besides that, our main purpose of shadowing is to add a `Comment` component below the main content. 39 | 40 | ```tsx 41 | // your-site/src/gatsby-theme-kb/components/Topic/index.tsx 42 | import React from 'react' 43 | import ThemeTopic, { 44 | Props as ThemeTopicProps, 45 | } from 'gatsby-theme-kb/src/components/Topic' 46 | import Comment from './Comment' 47 | 48 | interface TopicProps extends ThemeTopicProps {} 49 | 50 | const Topic = (props: TopicProps) => { 51 | return ( 52 | <> 53 | 54 |
55 | 56 |
57 | 58 | ) 59 | } 60 | 61 | export default Topic 62 | ``` 63 | 64 | ## The Comment component 65 | 66 | Here we choose [utterances](https://utteranc.es/) as the comment system. It is a lightweight system that uses GitHub issues. Please refer to its site for more details of setting up it to your github repository. 67 | 68 | This component is based on a tutorial [_How to Add Comments To Your GatsbyJS Blog In Less Than 10 Minutes | ahsanayaz.com_](https://ahsanayaz.com/adding-comments-to-your-gatsbyjs-blog/). With a little extra support of light/dark mode toggle. 69 | 70 | ```tsx 71 | // your-site/src/gatsby-theme-kb/components/Topic/Comment/index.tsx 72 | import React, { useEffect, memo } from 'react' 73 | import useDarkMode from 'use-dark-mode' 74 | 75 | type Props = { 76 | issueTerm: string 77 | } 78 | 79 | // you could choose other themes too 80 | const UTTERANCES_THEME_MAP = { 81 | light: 'github-light', 82 | dark: 'dark-blue', 83 | } 84 | 85 | // please change it to your own and make sure your repo has installed utterances app 86 | const REPO_NAME = 'hikerpig/gatsby-project-kb' 87 | 88 | const Comment: React.FC = memo(({ issueTerm }) => { 89 | const { value: isDark } = useDarkMode(false) 90 | const commentsUUID = `comments_${issueTerm}` 91 | 92 | useEffect(() => { 93 | let anchor 94 | const theme = isDark ? UTTERANCES_THEME_MAP.dark: UTTERANCES_THEME_MAP.light 95 | const script = document.createElement('script') 96 | anchor = document.getElementById(commentsUUID) 97 | script.setAttribute('src', 'https://utteranc.es/client.js') 98 | script.setAttribute('crossorigin', 'anonymous') 99 | script.async = true 100 | script.setAttribute('repo', REPO_NAME) 101 | script.setAttribute('issue-term', issueTerm) 102 | script.setAttribute('theme', theme) 103 | anchor.appendChild(script) 104 | return () => { 105 | anchor.innerHTML = '' 106 | } 107 | }) 108 | 109 | return ( 110 | <> 111 |
116 |
117 |
118 | 119 | ) 120 | }) 121 | 122 | export default Comment 123 | ``` 124 | -------------------------------------------------------------------------------- /demo/content/examples/mdx-components/FakeClock.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react' 2 | 3 | interface DemoProps {} 4 | 5 | const Demo = ({}: DemoProps) => { 6 | const [date, setDate] = useState(new Date()) 7 | 8 | useEffect(() => { 9 | const timerId = setInterval(() => { 10 | setDate(new Date()) 11 | }, 1000) 12 | 13 | return () => { 14 | window.clearInterval(timerId) 15 | } 16 | }) 17 | 18 | return ( 19 |

20 | A fake clock: 21 | 22 | {date.getHours()}:{date.getMinutes()}:{date.getSeconds()} 23 | 24 |

25 | ) 26 | } 27 | 28 | export default Demo 29 | -------------------------------------------------------------------------------- /demo/content/examples/mdx.mdx: -------------------------------------------------------------------------------- 1 | # MDX and custom components 2 | 3 | MDX is an extension to Markdown that lets you include JSX in Markdown documents. 4 | 5 | You can find so many posts on the internet to help understand the basic concepts and usage in a Gatsbyjs project. 6 | 7 | Some official tutorials: 8 | 9 | - [MDX | Gatsby](https://www.gatsbyjs.com/docs/glossary/mdx/) 10 | - [Writing Pages in MDX | Gatsby](https://www.gatsbyjs.com/docs/mdx/writing-pages/) 11 | 12 | ## Using with gatsby-theme-kb 13 | 14 | Here is an example of using custom components in this demo. [Check the latest code on github](https://github.com/hikerpig/gatsby-project-kb/tree/master/demo/content/examples). 15 | 16 | File structure: 17 | 18 | ``` 19 | demo/examples 20 | ├── mdx-components 21 | │   └── FakeClock.tsx 22 | ├── mdx.mdx 23 | ``` 24 | 25 | In your `.mdx` file: 26 | 27 | ```tsx 28 | import FakeClock from "./mdx-components/FakeClock.tsx" 29 | 30 | 31 | ``` 32 | 33 | The result: 34 | 35 | import FakeClock from "./mdx-components/FakeClock.tsx" 36 | 37 | -------------------------------------------------------------------------------- /demo/content/examples/override-styles.md: -------------------------------------------------------------------------------- 1 | Override Styles 2 | === 3 | 4 | If you want to customize this theme's appearance in your site, there are multiple ways to achieve it. 5 | 6 | ## Include your own styles for overriding 7 | 8 | You can import your own style files in your site's `gatsby-browser.js`. For example, see how this 9 | demo site [overrides and adds its own 10 | styles](https://github.com/hikerpig/gatsby-project-kb/blob/master/demo/gatsby-browser.js). 11 | 12 | ```js 13 | import './src/styles/prism-theme.css' 14 | import './src/styles/main.css' 15 | ``` 16 | 17 | ## Override gatsby-theme-kb css variables 18 | 19 | This is similar to the previous approach, but if you just want to change some colors, instead of rewriting all things on your own, it's better to override some of gatsby-theme-kb's builtin CSS variables. 20 | 21 | You can see them in the [latest source code](https://github.com/hikerpig/gatsby-project-kb/blob/master/packages/gatsby-theme-kb/src/styles/vars.css). 22 | 23 | ```css 24 | // obsidian nord 25 | :scope { 26 | --light-1: #F9FAFB; 27 | --light-2: #F3F4F6; 28 | --light-3: #E7E5E4; 29 | --light-4: #ffffff; 30 | 31 | --dark-1: #2e3440; 32 | --dark-2: #3b4252; 33 | --dark-3: #434c5e; 34 | --dark-4: #4c566a; 35 | 36 | --frost1: #8fbcbb; 37 | --frost2: #88c0d0; 38 | --frost3: #a1c4e6; 39 | --frost4: #81a1c1; 40 | 41 | --red: #bf616a; 42 | --orange: #d08770; 43 | --yellow: #ebcb8b; 44 | --green: #a3be8c; 45 | --purple: #b48ead; 46 | } 47 | 48 | /* default theme light */ 49 | body { 50 | --kb-link-color: #ff5449; 51 | --kb-tree-cur-color: #e7e5e4; 52 | --kb-font-family: 'Avenir', -apple-system, sans-serif; 53 | --kb-shadow-bg: rgba(0, 0, 0, 0.2); 54 | --kb-text-color: hsl(2deg 20% 15%); 55 | --kb-text-inverse-color: white; 56 | --kb-references-bg: #fafafa; 57 | --kb-search-highlight-bg: #eaeaea; 58 | --kb-note-bg: var(--bg-color-1); 59 | --kb-separator-color: #ddd; 60 | --kb-scrollbar-thumb: #ddd; 61 | --kb-blockquote-bg: #f6f6f6; 62 | 63 | --bg-color-1: #F9FAFB; 64 | --bg-color-2: #F3F4F6; 65 | --code-bg-color: #f0f0f0; 66 | --code-color: #333; 67 | } 68 | ``` 69 | 70 | Here is how the dark mode overrides some of the variables: 71 | 72 | ```css 73 | .dark-mode { 74 | --kb-link-color: var(--frost3); 75 | --kb-tree-cur-color: var(--dark-3); 76 | --kb-font-family: 'Avenir', -apple-system, sans-serif; 77 | --kb-shadow-bg: rgba(0, 0, 0, 0.2); 78 | --kb-text-color: #eceff4; 79 | --kb-text-inverse-color: white; 80 | --kb-references-bg: var(--dark-2); 81 | --kb-search-highlight-bg: var(--dark-3); 82 | --kb-separator-color: #666; 83 | --kb-scrollbar-thumb: var(--dark-4); 84 | --kb-blockquote-bg: #353c48; 85 | 86 | --bg-color-1: var(--dark-1); 87 | --bg-color-2: var(--dark-2); 88 | --code-bg-color: var(--dark-2); 89 | --code-color: var(--purple); 90 | } 91 | ``` 92 | 93 | ## Override graph view colors 94 | 95 | This theme uses [note-graph](https://github.com/hikerpig/note-graph) to show the relationship of the 96 | notes. note-graph uses a canvas for drawing, so usually it's not straightforward to change how it 97 | looks. 98 | 99 | note-graph do provide some methods to customize the colors. 100 | 101 | ### CSS Variables 102 | 103 | When initializing its theme, note-graph will try to read CSS variables on it's container's scope: 104 | 105 | ```text 106 | --notegraph-background: color of canvas background 107 | --notegraph-note-color-regular: color of normal node 108 | --notegraph-highlighted-foreground-color: border color of highlighted node 109 | --notegraph-link-color-regular: color of normal link 110 | --notegraph-link-color-highlighted: color of highlighted link 111 | ``` 112 | 113 | So it's possible to specify some essential colors of the theme by overriding the CSS variables. 114 | 115 | For example, apply the ayu palette to note-graph: 116 | 117 | ```css 118 | body { 119 | --notegraph-background: #fff; 120 | --notegraph-note-color-regular: #fdb05e; 121 | --notegraph-highlighted-foreground-color: #ff9838; 122 | --notegraph-link-color-regular: #ffbdbd; 123 | --notegraph-link-color-highlighted: #ff99bd; 124 | } 125 | ``` 126 | -------------------------------------------------------------------------------- /demo/content/examples/syntax-highlight.md: -------------------------------------------------------------------------------- 1 | Add syntax highlight 2 | === 3 | 4 | The `gatsby-theme-kb` does not cover syntax highlighting, it's up to your options to choose your syntax highlighter. Luckily, the Gatsby ecosystem has some pretty good plugins, [gatsby-remark-prismjs](https://www.gatsbyjs.com/plugins/gatsby-remark-prismjs/) can be a good start. 5 | 6 | Here is an example of add a remark plugin to `gatsby-theme-kb`. Since in this theme we use `gatsby-plugin-mdx` to process markdown files, **not** the `gatsby-transformer-remark`. 7 | 8 | ```js 9 | // a fragment of gatsby-config.js 10 | const path = require('path'); 11 | 12 | module.exports = { 13 | // ... 14 | plugins: [ 15 | { 16 | resolve: 'gatsby-theme-kb', 17 | options: { 18 | contentPath: path.resolve(__dirname, 'content'), 19 | getPluginMdx(defaultPluginMdx) { 20 | defaultPluginMdx.options.gatsbyRemarkPlugins.push({ 21 | resolve: 'gatsby-remark-prismjs', 22 | options: { 23 | noInlineHighlight: true, 24 | }, 25 | }) 26 | return defaultPluginMdx 27 | }, 28 | }, 29 | }, 30 | // ... 31 | ], 32 | }; 33 | ``` 34 | 35 | Choose one PrismJS theme from it's official site, or [prism-themes](https://github.com/PrismJS/prism-themes). 36 | 37 | In this demo site, I use the prism-nord theme, I download it into `src/styles/prism-theme.css`, and import it in `gatsby-browser.js`. 38 | 39 | ```js 40 | // gatsby-browser.js 41 | import './src/styles/prism-theme.css' 42 | ``` 43 | 44 | ## Other resources 45 | 46 | - You may try `gatsby-remark-shiki-twoslash` as [this issue mentioned](https://github.com/hikerpig/foam-template-gatsby-kb/issues/5#issuecomment-782902350). -------------------------------------------------------------------------------- /demo/content/features/graph-view.md: -------------------------------------------------------------------------------- 1 | Graph View 2 | === 3 | 4 | Click the 'Show Graph Visualisation' button on top-right to show a graph visualising the relationships - which are established by [[wiki-links]] - of your notes. You can even searc your notes and get result nodes highlighted as you search. 5 | 6 | The graph is rendered by [note-graph]. 7 | 8 | If you want to customize the colors of the graph, please check [[override-styles]] for instruction. 9 | 10 | 11 | ![](https://i.loli.net/2020/12/07/e9iKhFIvqcDOdCz.png) 12 | 13 | [note-graph]: https://github.com/hikerpig/note-graph 14 | -------------------------------------------------------------------------------- /demo/content/features/table-of-contents.md: -------------------------------------------------------------------------------- 1 | Show Table Of Contents 2 | === 3 | 4 | `gatsby-theme-kb` can be configured to have different placements of auto-generated table of contents. 5 | 6 | Suported option type is `false \| Array<'inline' | 'sidebar'>`. 7 | 8 | By default, the value is `['sidebar']`, so if you want to enable the `inline` behavior, please apply the respective option. 9 | 10 | For example: 11 | 12 | ```js 13 | { 14 | resolve: 'gatsby-theme-kb', 15 | options: { 16 | tocTypes: ['inline', 'sidebar'], 17 | }, 18 | } 19 | ``` 20 | 21 | 22 | ## sidebar 23 | 24 | Position the TOC in the sidebar. 25 | 26 | ![sidebar-toc](https://i.loli.net/2021/10/24/W1BMmUQZOyk8ixS.png) 27 | 28 | The TOC sidebar can also be triggered in mobile mode. 29 | 30 | ![sidebar-mobile-toc](https://i.loli.net/2021/10/24/J7TiNrv43xePb9U.png) 31 | 32 | ## inline 33 | 34 | Some people would prefer to see the table of contents inline content on top of the page. 35 | 36 | ![inline-toc](https://i.loli.net/2021/10/24/TfoKMuxWIEbipXV.png) 37 | -------------------------------------------------------------------------------- /demo/content/features/using-frontmatter.md: -------------------------------------------------------------------------------- 1 | Using frontmatter 2 | === 3 | 4 | ## Some special fields 5 | 6 | ### `title` 7 | 8 | This will set the page title of a topic page. 9 | 10 | ```yaml 11 | --- 12 | title: Zettelkasten 13 | --- 14 | ``` 15 | 16 | If you have not specified title in frontmatter, `gatsby-theme-kb` will extract the first `h1` as title of the page. 17 | 18 | ### `private` to hide it from publishing 19 | 20 | You can prevent the topic from being published by setting `private: True` in frontmatter. 21 | 22 | ```markdown 23 | --- 24 | private: True 25 | --- 26 | 27 | ## Some private or temporary stuff 28 | ``` 29 | -------------------------------------------------------------------------------- /demo/content/features/wiki-links.md: -------------------------------------------------------------------------------- 1 | # Wiki Link 2 | 3 | A wiki-link is a link text wrapped inside double brackets `[[]]`. 4 | 5 | ## Some further details 6 | 7 | ### Anchor reference 8 | 9 | > NOTICE: This is non-standard for wiki links, but I found it quite suit to my needs so I implement it in gatsby-project-kb, and Obsidian has this support, too. 10 | 11 | You can refer to a topic's specific section by anchor text, which is after the hashtag `#`. 12 | 13 | For example, for a target topic with the structure as below. 14 | 15 | ```text 16 | # header 1 17 | ## header 2 18 | ``` 19 | 20 | It's possible to link to the second header with `[[topic#header 2]]`. The target url will be `topic#header-2`, with the anchor text processed by `slugify`. 21 | 22 | ## About markdown link 23 | 24 | This theme is also capable of [extract plain markdowndown internal links](https://github.com/hikerpig/gatsby-project-kb/issues/53) and show them in backlinks. 25 | 26 | ```md 27 | A paragraph with a [markdown link](../some-other-file) 28 | ``` 29 | 30 | Currently only relative link **without** file extension will be recognized. 31 | 32 | ```md 33 | This [won't work](../some-other-file.md) 34 | ``` 35 | -------------------------------------------------------------------------------- /demo/content/readme.md: -------------------------------------------------------------------------------- 1 | # Gatsby knowledge base theme 2 | 3 | This is a Gatsby theme for publishing a knowledge base or personal wiki. Named `gatsby-theme-kb`. 4 | 5 | Create your [Second Brain](https://www.buildingasecondbrain.com/) by writing down your thoughts - or as the term used this theme `topics` - and their relations in markdown. 6 | 7 | Heavily inspired by [gatsby-digital-garden](https://github.com/mathieudutour/gatsby-digital-garden) and [Obsidian](https://publish.obsidian.md/help/Index). 8 | 9 | ## ✨ Features 10 | 11 | - Support bidirectional [[wiki-links]] in double brackets `[[]]`, will show the backlink reference context. 12 | - Hover preview for wiki-links. 13 | - A nice interactive [[graph-view]] visualizing the relationships of your notes. 14 | - Mobile-friendly responsive design. 15 | - Local search. 16 | - Light and dark mode. 17 | - Auto-generated sidebar based on notes directory. 18 | - Auto-generated [[table-of-contents]]. 19 | - Configurable `mdx` processing system, with the power of `gatsby-plugin-mdx`. 20 | - Page customization by [[using-frontmatter]]. 21 | 22 | This demo site has some extra gatsby config apart from `gatsby-theme-kb` itself. You can [find them on github](https://github.com/hikerpig/gatsby-project-kb/blob/master/demo/gatsby-config.js). 23 | 24 | ## Working with knowledge management tools 25 | 26 | ### Foam 27 | 28 | [Foam](https://foambubble.github.io/foam/) is a personal knowledge management and sharing system inspired by Roam Research, built on Visual Studio Code and GitHub. 29 | 30 | But it doesn't bundle with an official publishing system (yet). 31 | 32 | And `gatsby-theme-kb` is one of the few Foam publishing solutions that support note graph rendering. 33 | 34 | With the help of [Foam for VSCode](https://marketplace.visualstudio.com/items?itemName=foam.foam-vscode) plugin auto-creating link definitions, your knowledge base can have nested folders. 35 | 36 | I've created a Foam template [foam-template-gatsby-kb](https://github.com/hikerpig/foam-template-gatsby-kb/) to help you start. It can also be used to publish an Obsidian vault. There are some detailed instructions in its readme. 37 | 38 | ### Obsidian 39 | 40 | This theme can be used to publish an Obsidian project. 41 | 42 | Though currently this is far less versatile than Obsidian's publishing system. e.g. lack of tagging system. 43 | 44 | But this is free and open, you can always extend it as you wish. 45 | 46 | ## Extending it in your Gatsby site 47 | 48 | - [Shadowing in Gatsby Themes](https://www.gatsbyjs.com/docs/how-to/plugins-and-themes/shadowing/), Gatsby offical tutorial about extending a theme. 49 | - Extend `gatsby-theme-kb` to [[comment-system]]. 50 | - [[override-styles]] shows some approaches to change the appearance of the site. 51 | 52 | ## Any Thoughts to make this better? 53 | 54 | Welcome to open issues and PRs on [github repo](https://github.com/hikerpig/gatsby-project-kb). 55 | 56 | [wiki-links]: ./features/wiki-links.md 57 | [graph-view]: ./features/graph-view.md 58 | [using-frontmatter]: ./features/using-frontmatter.md 59 | [comment-system]: ./examples/comment-system 60 | [override-styles]: ./examples/override-styles 61 | -------------------------------------------------------------------------------- /demo/content/showcase.md: -------------------------------------------------------------------------------- 1 | # Showcase 2 | 3 | - [My own wiki](http://wiki.hikerpig.cn/), there are some custom gatsby configs, you can check that in [github repo](https://github.com/hikerpig/wiki). -------------------------------------------------------------------------------- /demo/content/todo.md: -------------------------------------------------------------------------------- 1 | # Todo 2 | 3 | - [X] Setup the theme 4 | - [X] Complete the graph view 5 | - [X] Add local search 6 | - [X] Responsive design 7 | - [X] Collapsable sidebar tree 8 | - [X] Support nested folder without the chore of manually adding link definitions 9 | - [X] Make Mobile TOC view available in mobile 10 | - [X] Better style for graph-view 11 | - [ ] Knobs to config the force graph in graph-view 12 | -------------------------------------------------------------------------------- /demo/gatsby-browser.js: -------------------------------------------------------------------------------- 1 | import './src/styles/prism-theme.css' 2 | import './src/styles/main.css' 3 | -------------------------------------------------------------------------------- /demo/gatsby-config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | const pathPrefix = process.env.KB_BASE_PATH || '/' 4 | 5 | module.exports = { 6 | pathPrefix, 7 | siteMetadata: { 8 | title: `gatsby-theme-kb`, 9 | description: `Your personal knowledge base`, 10 | author: `@hikerpig`, 11 | }, 12 | plugins: [ 13 | { 14 | resolve: 'gatsby-theme-kb', 15 | options: { 16 | contentPath: path.resolve(__dirname, 'content'), 17 | wikiLinkLabelTemplate: '[[{{ title }}]]', 18 | getPluginMdx(defaultPluginMdx) { 19 | defaultPluginMdx.options.gatsbyRemarkPlugins.push({ 20 | resolve: 'gatsby-remark-prismjs', 21 | options: { 22 | noInlineHighlight: true, 23 | }, 24 | }) 25 | return defaultPluginMdx 26 | }, 27 | }, 28 | }, 29 | 'gatsby-plugin-no-sourcemaps', 30 | ], 31 | } 32 | -------------------------------------------------------------------------------- /demo/gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/no-danger */ 2 | import React from 'react' 3 | 4 | /** 5 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 6 | * 7 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 8 | */ 9 | 10 | export const onPreRenderHTML = ({ 11 | getPreBodyComponents, 12 | replacePreBodyComponents, 13 | }) => { 14 | const preBodyComponents = getPreBodyComponents() 15 | 16 | const cornerText = ` 17 | 18 | ` 19 | 20 | preBodyComponents.push(
) 21 | replacePreBodyComponents(preBodyComponents) 22 | } 23 | -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "version": "1.4.6", 4 | "name": "demo", 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "develop", 8 | "build": "gatsby build --prefix-paths", 9 | "develop": "gatsby develop", 10 | "clean": "gatsby clean" 11 | }, 12 | "dependencies": { 13 | "gatsby": "^4.4.0", 14 | "gatsby-plugin-no-sourcemaps": "^2.8.0", 15 | "gatsby-remark-prismjs": "^3.13.0", 16 | "gatsby-theme-kb": "^0.9.4", 17 | "prismjs": "^1.23.0", 18 | "react": "^17", 19 | "react-dom": "^17" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /demo/src/gatsby-theme-kb/components/Topic/Comment/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, memo } from 'react' 2 | import useDarkMode from 'use-dark-mode' 3 | 4 | type Props = { 5 | issueTerm: string 6 | } 7 | 8 | // you could choose other themes too 9 | const UTTERANCES_THEME_MAP = { 10 | light: 'github-light', 11 | dark: 'dark-blue', 12 | } 13 | 14 | // please change it to your own and make sure your repo has installed utterances app 15 | const REPO_NAME = 'hikerpig/gatsby-project-kb' 16 | 17 | const Comment: React.FC = memo(({ issueTerm }) => { 18 | const { value: isDark } = useDarkMode(false) 19 | const commentsUUID = `comments_${issueTerm}` 20 | 21 | useEffect(() => { 22 | let anchor 23 | const theme = isDark ? UTTERANCES_THEME_MAP.dark: UTTERANCES_THEME_MAP.light 24 | const script = document.createElement('script') 25 | anchor = document.getElementById(commentsUUID) 26 | script.setAttribute('src', 'https://utteranc.es/client.js') 27 | script.setAttribute('crossorigin', 'anonymous') 28 | script.async = true 29 | script.setAttribute('repo', REPO_NAME) 30 | script.setAttribute('issue-term', issueTerm) 31 | script.setAttribute('theme', theme) 32 | script.setAttribute('label', 'comment') 33 | anchor.appendChild(script) 34 | return () => { 35 | anchor.innerHTML = '' 36 | } 37 | }) 38 | 39 | return ( 40 | <> 41 |
46 |
47 |
48 | 49 | ) 50 | }) 51 | 52 | export default Comment 53 | -------------------------------------------------------------------------------- /demo/src/gatsby-theme-kb/components/Topic/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ThemeTopic, { 3 | Props as ThemeTopicProps, 4 | } from 'gatsby-theme-kb/src/components/Topic' 5 | import Comment from './Comment' 6 | 7 | interface TopicProps extends ThemeTopicProps {} 8 | 9 | const Topic = (props: TopicProps) => { 10 | return ( 11 | <> 12 | 13 |
14 | 15 |
16 | 17 | ) 18 | } 19 | 20 | export default Topic 21 | -------------------------------------------------------------------------------- /demo/src/styles/main.css: -------------------------------------------------------------------------------- 1 | /* ---------------- prism override ---------------------- */ 2 | pre[class*="language-"] { 3 | margin: 1em 0; 4 | } 5 | 6 | .dark-mode pre[class*="language-"] { 7 | background-color: #252931; 8 | } 9 | 10 | .light-mode pre[class*="language-"] { 11 | background-color: #2b2727; 12 | } 13 | 14 | /* ----------------end prism override ------------------- */ 15 | 16 | code { 17 | font-size: 0.9em; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /demo/src/styles/prism-theme.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Nord Theme Originally by Arctic Ice Studio 3 | * https://nordtheme.com 4 | * 5 | * Ported for PrismJS by Zane Hitchcoxc (@zwhitchcox) and Gabriel Ramos (@gabrieluizramos) 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: #f8f8f2; 11 | background: none; 12 | font-family: "Fira Code", Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 13 | text-align: left; 14 | white-space: pre; 15 | word-spacing: normal; 16 | word-break: normal; 17 | word-wrap: normal; 18 | line-height: 1.5; 19 | -moz-tab-size: 4; 20 | -o-tab-size: 4; 21 | tab-size: 4; 22 | -webkit-hyphens: none; 23 | -moz-hyphens: none; 24 | -ms-hyphens: none; 25 | hyphens: none; 26 | } 27 | 28 | /* Code blocks */ 29 | pre[class*="language-"] { 30 | padding: 1em; 31 | margin: .5em 0; 32 | overflow: auto; 33 | border-radius: 0.3em; 34 | } 35 | 36 | :not(pre) > code[class*="language-"], 37 | pre[class*="language-"] { 38 | background: #2E3440; 39 | } 40 | 41 | /* Inline code */ 42 | :not(pre) > code[class*="language-"] { 43 | padding: .1em; 44 | border-radius: .3em; 45 | white-space: normal; 46 | } 47 | 48 | .token.comment, 49 | .token.prolog, 50 | .token.doctype, 51 | .token.cdata { 52 | color: #636f88; 53 | } 54 | 55 | .token.punctuation { 56 | color: #81A1C1; 57 | } 58 | 59 | .namespace { 60 | opacity: .7; 61 | } 62 | 63 | .token.property, 64 | .token.tag, 65 | .token.constant, 66 | .token.symbol, 67 | .token.deleted { 68 | color: #81A1C1; 69 | } 70 | 71 | .token.number { 72 | color: #B48EAD; 73 | } 74 | 75 | .token.boolean { 76 | color: #81A1C1; 77 | } 78 | 79 | .token.selector, 80 | .token.attr-name, 81 | .token.string, 82 | .token.char, 83 | .token.builtin, 84 | .token.inserted { 85 | color: #A3BE8C; 86 | } 87 | 88 | .token.operator, 89 | .token.entity, 90 | .token.url, 91 | .language-css .token.string, 92 | .style .token.string, 93 | .token.variable { 94 | color: #81A1C1; 95 | } 96 | 97 | .token.atrule, 98 | .token.attr-value, 99 | .token.function, 100 | .token.class-name { 101 | color: #88C0D0; 102 | } 103 | 104 | .token.keyword { 105 | color: #81A1C1; 106 | } 107 | 108 | .token.regex, 109 | .token.important { 110 | color: #EBCB8B; 111 | } 112 | 113 | .token.important, 114 | .token.bold { 115 | font-weight: bold; 116 | } 117 | 118 | .token.italic { 119 | font-style: italic; 120 | } 121 | 122 | .token.entity { 123 | cursor: help; 124 | } -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "independent", 3 | "registry": "https://registry.npmjs.org/", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "npmClient": "yarn", 8 | "useWorkspaces": true, 9 | "packages": [ 10 | "packages/*", 11 | "demo" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-project-kb", 3 | "private": true, 4 | "devDependencies": { 5 | "@types/react": "^17.0.0", 6 | "@types/react-dom": "^17.0.0", 7 | "gatsby": "^4.0.0", 8 | "lerna": "^4.0.0", 9 | "react": "^17.0.0", 10 | "react-dom": "^17.0.0", 11 | "tsdx": "^0.14.1", 12 | "typescript": "^4.1.2" 13 | }, 14 | "workspaces": [ 15 | "packages/*", 16 | "demo" 17 | ], 18 | "scripts": { 19 | "lerna": "lerna", 20 | "demo:clean": "yarn workspace demo clean", 21 | "dev": "yarn workspace demo develop", 22 | "demo:build": "NODE_ENV=production yarn workspace demo build", 23 | "test": "lerna run test --", 24 | "lint": "lerna run lint -- --fix", 25 | "build": "yarn demo:build", 26 | "prepublish": "lerna run prepublish", 27 | "start:app": "yarn run build && yarn --cwd example && yarn --cwd example start" 28 | }, 29 | "version": null 30 | } 31 | -------------------------------------------------------------------------------- /packages/gatsby-remark-wiki-link/.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | -------------------------------------------------------------------------------- /packages/gatsby-remark-wiki-link/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [0.4.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-remark-wiki-link@0.4.0-alpha.0...gatsby-remark-wiki-link@0.4.0) (2022-02-06) 7 | 8 | **Note:** Version bump only for package gatsby-remark-wiki-link 9 | 10 | 11 | 12 | 13 | 14 | ## [0.3.1](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-remark-wiki-link@0.3.0...gatsby-remark-wiki-link@0.3.1) (2021-10-24) 15 | 16 | **Note:** Version bump only for package gatsby-remark-wiki-link 17 | 18 | 19 | 20 | 21 | 22 | # [0.3.0-alpha.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-remark-wiki-link@0.2.0...gatsby-remark-wiki-link@0.3.0-alpha.0) (2021-04-02) 23 | 24 | 25 | ### Features 26 | 27 | * Add anchor reference support, related [#8](https://github.com/hikerpig/gatsby-project-kb/issues/8) ([3c0d13a](https://github.com/hikerpig/gatsby-project-kb/commit/3c0d13a78146dc9b6bf1215af367fbd1e3a999d4)) 28 | -------------------------------------------------------------------------------- /packages/gatsby-remark-wiki-link/README.md: -------------------------------------------------------------------------------- 1 | # `gatsby-remark-wiki-link` 2 | 3 | Transform `[[Link to page]]` into `[Link to page](titleToURL('Link to page'))`. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | npm install gatsby-remark-wiki-link 9 | ``` 10 | 11 | ## Usage 12 | 13 | Add the plugin to your Gatsby config: 14 | 15 | ```js 16 | { 17 | resolve: `gatsby-plugin-mdx`, 18 | options: { 19 | gatsbyRemarkPlugins: [ 20 | { 21 | resolve: `gatsby-remark-wiki-link`, 22 | }, 23 | ], 24 | }, 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /packages/gatsby-remark-wiki-link/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-remark-wiki-link", 3 | "version": "0.4.1", 4 | "description": "A gatsby remark plugin for parsing wiki-link in markdown", 5 | "author": "hikerpig ", 6 | "homepage": "https://github.com/hikerpig/gatsby-project-kb#readme", 7 | "license": "MIT", 8 | "main": "lib/index.js", 9 | "directories": { 10 | "lib": "lib", 11 | "test": "__tests__" 12 | }, 13 | "files": [ 14 | "lib" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/hikerpig/gatsby-project-kb.git" 19 | }, 20 | "scripts": { 21 | "prepublish": "tsc", 22 | "watch": "tsc --watch", 23 | "build": "tsc" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/hikerpig/gatsby-project-kb/issues" 27 | }, 28 | "devDependencies": { 29 | "@types/unist": "^2.0.6", 30 | "typescript": "^4.1.3" 31 | }, 32 | "dependencies": { 33 | "slugify": "^1.4.6", 34 | "unist-util-visit": "^2.0.3" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/gatsby-remark-wiki-link/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as visit from 'unist-util-visit' 2 | import { Node } from 'unist' 3 | import { LinkReference, Definition, Link, Text, StaticPhrasingContent } from 'mdast' 4 | import slugify from 'slugify' 5 | import * as path from 'path' 6 | 7 | interface LinkReferenceNode extends LinkReference { 8 | url?: string; 9 | title?: string; 10 | } 11 | 12 | /** 13 | * if title is something like `folder1/folder2/name`, 14 | * will slugify the name, while keeping the folder names 15 | */ 16 | const defaultTitleToURLPath = (title: string) => { 17 | const segments = title.split('/') 18 | let titleCandidate = segments.pop() as string 19 | const hashIndex = titleCandidate.indexOf('#') 20 | if (hashIndex > -1) { 21 | titleCandidate = titleCandidate.substring(0, hashIndex) 22 | } 23 | const slugifiedTitle = slugify(titleCandidate) 24 | return `${segments.join('/')}/${slugifiedTitle}` 25 | } 26 | 27 | const processWikiLinks = ( 28 | { markdownAST }: { markdownAST: Node }, 29 | options?: { titleToURLPath?: string; stripBrackets?: boolean, stripDefinitionExts?: string[] } 30 | ) => { 31 | const { stripDefinitionExts } = options 32 | const titleToURL = options?.titleToURLPath 33 | ? require(options.titleToURLPath) 34 | : defaultTitleToURLPath 35 | 36 | const definitions: { [identifier: string]: Definition } = {} 37 | 38 | const getLinkInfo = (definition: Definition) => { 39 | if (typeof definition.identifier !== 'string') return 40 | let linkUrl = definition.url 41 | const isExternalLink = /\/\//.test(linkUrl) 42 | let shouldReplace = !isExternalLink 43 | if (shouldReplace && stripDefinitionExts) { 44 | const extname = path.extname(definition.url || '') 45 | const matchedExtname = stripDefinitionExts.find((n) => extname === n) 46 | if (matchedExtname) { 47 | linkUrl = linkUrl.slice(0, linkUrl.length - matchedExtname.length) 48 | } 49 | } 50 | return { 51 | linkUrl, 52 | shouldReplace 53 | } 54 | } 55 | 56 | visit(markdownAST, `definition`, (node: Definition) => { 57 | if (!node.identifier || typeof node.identifier !== 'string') { 58 | return 59 | } 60 | definitions[node.identifier] = node 61 | }) 62 | visit(markdownAST, `linkReference`, (node: LinkReferenceNode, index, parent) => { 63 | if (node.referenceType !== 'shortcut') { 64 | return 65 | } 66 | 67 | const definition = definitions[node.identifier] 68 | const linkInfo = definition ? getLinkInfo(definition): null 69 | const linkUrl = linkInfo ? linkInfo.linkUrl: definition?.url 70 | if ((linkInfo && !linkInfo.shouldReplace)) { 71 | // console.log('should not replace', definitions, node.identifier) 72 | return 73 | } 74 | 75 | const siblings = parent.children 76 | if (!siblings || !Array.isArray(siblings)) { 77 | return 78 | } 79 | const previous: StaticPhrasingContent = siblings[index - 1] as any 80 | const next: StaticPhrasingContent = siblings[index + 1] as any 81 | 82 | if (!(previous && next)) { 83 | return 84 | } 85 | 86 | if (!('value' in previous && 'value' in next)) { 87 | return 88 | } 89 | 90 | const previousValue = previous.value as string 91 | const nextValue = next.value as string 92 | 93 | if ( 94 | previous.type !== 'text' || 95 | previous.value[previousValue.length - 1] !== '[' || 96 | next.type !== 'text' || 97 | next.value[0] !== ']' 98 | ) { 99 | return 100 | } 101 | 102 | previous.value = previousValue.replace(/\[$/, '') 103 | next.value = nextValue.replace(/^\]/, '') 104 | 105 | ;(node as any).type = 'link' // cast it to link 106 | if (definition) { 107 | node.url = linkUrl 108 | } else { 109 | node.url = titleToURL(node.label as string) 110 | } 111 | node.title = node.label 112 | if (!options?.stripBrackets && Array.isArray(node.children)) { 113 | const firstChild = node.children[0]; 114 | if (firstChild && 'value' in firstChild) { 115 | firstChild.value = `[[${firstChild.value}]]` 116 | } 117 | } 118 | delete node.label 119 | delete node.referenceType 120 | delete node.identifier 121 | }) 122 | } 123 | 124 | // default export may have issue being loaded by gatsby-plugin-mdx 125 | // see https://github.com/gatsbyjs/gatsby/issues/34015 126 | // export default processWikiLinks 127 | 128 | export = processWikiLinks 129 | -------------------------------------------------------------------------------- /packages/gatsby-remark-wiki-link/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": false, 10 | "lib": ["es5", "dom"], 11 | "types": ["jest", "node"], 12 | "typeRoots": ["node_modules/@types"], 13 | "jsx": "react", 14 | "skipLibCheck": true 15 | }, 16 | "include": ["src/**/*.ts"], 17 | "exclude": ["node_modules/**"], 18 | "compileOnSave": false 19 | } 20 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # dotenv environment variable files 55 | .env* 56 | 57 | # gatsby files 58 | .cache/ 59 | public 60 | 61 | # Mac files 62 | .DS_Store 63 | 64 | # Yarn 65 | yarn-error.log 66 | .pnp/ 67 | .pnp.js 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/.prettierignore: -------------------------------------------------------------------------------- 1 | .cache 2 | package.json 3 | package-lock.json 4 | public 5 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/.yarnrc: -------------------------------------------------------------------------------- 1 | registry https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [0.9.3](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.9.2...gatsby-theme-kb@0.9.3) (2022-03-26) 7 | 8 | 9 | ### Bug Fixes 10 | 11 | * **gatsby-theme-kb:** apply options.ignore to transformer-wiki-references plugin ([9190eee](https://github.com/hikerpig/gatsby-project-kb/commit/9190eee3ec23484cabdf368793cadb8b0a3458ec)) 12 | * **gatsby-theme-kb:** fix reference resolving bug when they are in nested folder ([0e99099](https://github.com/hikerpig/gatsby-project-kb/commit/0e9909994b9c33c1567e52e7d0eb0720cb937d83)) 13 | 14 | 15 | 16 | 17 | 18 | ## [0.9.1](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.9.0...gatsby-theme-kb@0.9.1) (2022-03-20) 19 | 20 | 21 | ### Bug Fixes 22 | 23 | * **gatsby-theme-kb:** page name should be slugified during createPage ([#45](https://github.com/hikerpig/gatsby-project-kb/issues/45)) ([06e2741](https://github.com/hikerpig/gatsby-project-kb/commit/06e2741f748d8fd1dee3f04c37da8b902e9d3f29)) 24 | 25 | 26 | 27 | 28 | 29 | # [0.9.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.9.0-alpha.4...gatsby-theme-kb@0.9.0) (2022-02-06) 30 | 31 | **Note:** Version bump only for package gatsby-theme-kb 32 | 33 | 34 | 35 | 36 | 37 | # [0.8.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.7.8...gatsby-theme-kb@0.8.0) (2021-10-24) 38 | 39 | 40 | ### Features 41 | 42 | * **demo:** an example of shadowing by adding a comment, close [#24](https://github.com/hikerpig/gatsby-project-kb/issues/24) ([5628ccf](https://github.com/hikerpig/gatsby-project-kb/commit/5628ccf2c0f57b2621398b0e82b7efefba05e065)) 43 | * **gatsby-theme-kb:** Add toc menu in mobile mode ([a82e9b4](https://github.com/hikerpig/gatsby-project-kb/commit/a82e9b48f78c2ed5fbb42227cd08c40cadb9502c)) 44 | * **gatsby-theme-kb:** adjust blockquote style a little ([e125ce4](https://github.com/hikerpig/gatsby-project-kb/commit/e125ce40c0c104e1d0e0a2941f933b11bc0c0c9d)) 45 | * **gatsby-theme-kb:** configurable toc, both `inline` and `sidebar` ([e3be6cc](https://github.com/hikerpig/gatsby-project-kb/commit/e3be6cc9fef3e2f94a0971106a5c838c8257cf78)) 46 | * **gatsby-theme-kb:** upgrade `gatsby-plugin-purgecss` ([35936a6](https://github.com/hikerpig/gatsby-project-kb/commit/35936a66b74c8421f603c0ed8d8a7d6d24a9427a)) 47 | 48 | 49 | 50 | 51 | 52 | # [0.7.0-alpha.3](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.7.0-alpha.2...gatsby-theme-kb@0.7.0-alpha.3) (2021-04-28) 53 | 54 | **Note:** Version bump only for package gatsby-theme-kb 55 | 56 | 57 | 58 | 59 | 60 | # [0.7.0-alpha.2](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.7.0-alpha.1...gatsby-theme-kb@0.7.0-alpha.2) (2021-04-19) 61 | 62 | **Note:** Version bump only for package gatsby-theme-kb 63 | 64 | 65 | 66 | 67 | 68 | # [0.7.0-alpha.1](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.7.0-alpha.0...gatsby-theme-kb@0.7.0-alpha.1) (2021-04-07) 69 | 70 | 71 | ### Bug Fixes 72 | 73 | * should ignore directory in contentTree ([5d14716](https://github.com/hikerpig/gatsby-project-kb/commit/5d14716a9287ac1d12e52f43105535c851c582fb)) 74 | 75 | 76 | ### Performance Improvements 77 | 78 | * optimize SiteSidebar and TreeView performance ([42c9102](https://github.com/hikerpig/gatsby-project-kb/commit/42c9102e7d7716545a26a4f5ae4dcb1855f5fbb9)) 79 | 80 | 81 | 82 | 83 | 84 | # [0.7.0-alpha.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.6.0...gatsby-theme-kb@0.7.0-alpha.0) (2021-04-02) 85 | 86 | 87 | ### Features 88 | 89 | * Add anchor reference support, related [#8](https://github.com/hikerpig/gatsby-project-kb/issues/8) ([3c0d13a](https://github.com/hikerpig/gatsby-project-kb/commit/3c0d13a78146dc9b6bf1215af367fbd1e3a999d4)) 90 | * better wiki references resolving with `contentPath` option ([46b66a9](https://github.com/hikerpig/gatsby-project-kb/commit/46b66a973bbdd702dfadb523e9ab0ab91ed1d417)) 91 | 92 | 93 | 94 | 95 | 96 | ## [0.6.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.5.4-alpha.0...gatsby-theme-kb@0.6.0) (2021-03-05) 97 | 98 | Hello Gatsby V3. 99 | 100 | # BREAKING 101 | 102 | Now works with gatsby@3 103 | 104 | # Improvements 105 | * upgrade gatsby-plugin-mdx@2 106 | * fix(gatsby-theme-kb): sidebar expand bug with file in nested folder 107 | * style: a warmer color for light mode default text 108 | 109 | 110 | ## [0.5.4-alpha.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.5.3...gatsby-theme-kb@0.5.4-alpha.0) (2021-03-04) 111 | 112 | **Note:** Version bump only for package gatsby-theme-kb 113 | 114 | 115 | 116 | 117 | 118 | ## [0.5.3](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.5.2...gatsby-theme-kb@0.5.3) (2021-03-03) 119 | 120 | 121 | ### Bug Fixes 122 | 123 | * **gatsby-theme-kb:** the sidebar subdirectory should not collapse when clicking link ([3a97a55](https://github.com/hikerpig/gatsby-project-kb/commit/3a97a55b86df0f2934f311ee6b237dae3ea7b865)) 124 | 125 | 126 | 127 | 128 | 129 | ## [0.5.2](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.5.1...gatsby-theme-kb@0.5.2) (2021-02-28) 130 | 131 | 132 | ### Bug Fixes 133 | 134 | * **gatsby-theme-kb:** errors when rendering custom components in mdx mentioned in [#6](https://github.com/hikerpig/gatsby-project-kb/issues/6) ([006b87c](https://github.com/hikerpig/gatsby-project-kb/commit/006b87c3372908ae09f73bb9476171dfef279e05)) 135 | 136 | 137 | 138 | 139 | 140 | ## [0.5.1](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.5.0...gatsby-theme-kb@0.5.1) (2021-02-26) 141 | 142 | 143 | ### Bug Fixes 144 | 145 | * codeblock style ([a837db8](https://github.com/hikerpig/gatsby-project-kb/commit/a837db867f55af6ca4133e1eb1fb2235e543a553)) 146 | * **gatsby-theme-kb:** graph view error due to lazy render ([fea20ff](https://github.com/hikerpig/gatsby-project-kb/commit/fea20ffbb4262e36d5adf707159f13c088d8842c)) 147 | 148 | 149 | 150 | 151 | 152 | # [0.5.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.4.3...gatsby-theme-kb@0.5.0) (2021-02-20) 153 | 154 | 155 | ### Features 156 | 157 | * add search in graph view and make it interactively highlighting result nodes ([0323db9](https://github.com/hikerpig/gatsby-project-kb/commit/0323db9ca8f8169d001b021724ca49714b5f10e4)) 158 | 159 | 160 | 161 | 162 | 163 | ## [0.4.3](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.4.2...gatsby-theme-kb@0.4.3) (2021-02-15) 164 | 165 | 166 | ### Bug Fixes 167 | 168 | * modify gatsby-plugin-purgecss to make it work in foam-template-gatsby-kb ([eea174a](https://github.com/hikerpig/gatsby-project-kb/commit/eea174afb86a8852e7e70bdfcfe09f0e52cfd700)) 169 | * multiple note-graph ini in GraphView when toggling graphState ([51581b7](https://github.com/hikerpig/gatsby-project-kb/commit/51581b7396b2edc00b9cb01a506d726eecc03036)) 170 | 171 | 172 | 173 | 174 | 175 | ## [0.4.2](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.4.1...gatsby-theme-kb@0.4.2) (2021-02-14) 176 | 177 | 178 | ### Bug Fixes 179 | 180 | * **gatsby-theme-kb:** sidebar treeview with nested folders ([77c6e2f](https://github.com/hikerpig/gatsby-project-kb/commit/77c6e2f4635010cc5db8037d089a04e346bfcc8d)) 181 | 182 | 183 | 184 | 185 | 186 | ## [0.4.1](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.4.0...gatsby-theme-kb@0.4.1) (2021-02-14) 187 | 188 | 189 | ### Bug Fixes 190 | 191 | * **gatsby-theme-kb:** misfunction in AnchorTag caused by v0.3.0 ([7739b49](https://github.com/hikerpig/gatsby-project-kb/commit/7739b496866eb6573dad0600fa252cd292aa1348)) 192 | * backlink should show referrer title and link ([8e89b4d](https://github.com/hikerpig/gatsby-project-kb/commit/8e89b4d22f85a2dc3b0f4902f9530a4692e81161)) 193 | 194 | 195 | 196 | 197 | 198 | # [0.4.0](https://github.com/hikerpig/gatsby-project-kb/compare/gatsby-theme-kb@0.3.0...gatsby-theme-kb@0.4.0) (2021-02-13) 199 | 200 | 201 | ### Features 202 | 203 | * **gatsby-theme-kb:** show backlink context, related [#1](https://github.com/hikerpig/gatsby-project-kb/issues/1) ([685b92c](https://github.com/hikerpig/gatsby-project-kb/commit/685b92c3970116cc593581f52ecc6e0b66b0c146)) 204 | 205 | 206 | ## 0.3.1 (2021-02-13) 207 | 208 | ### Features 209 | 210 | * **gatsby-theme-kb:** initially collapsed directory node ([cd0aae4](https://github.com/hikerpig/gatsby-project-kb/commit/cd0aae468c7c7755da813615c7a24c81431f53cb)) 211 | * optimize search result background in dark mode ([9af3ca3](https://github.com/hikerpig/gatsby-project-kb/commit/9af3ca3aa725f25f83303a17c922db8802c007e6)) 212 | * **gatsby-remark-wiki-link:** support `options.stripDefinitionExts ([7999c4c](https://github.com/hikerpig/gatsby-project-kb/commit/7999c4ce2ed89e313a9bd922c4582c3b0e457fdf)) 213 | * **gatsby-theme-kb:** `options.getPluginMdx` ([c307ae5](https://github.com/hikerpig/gatsby-project-kb/commit/c307ae530806797cac3974a1bcea480e931d730d)) 214 | * add custom package transformer-wiki-references and gatsby-remark-wiki-link ([237c94f](https://github.com/hikerpig/gatsby-project-kb/commit/237c94f06b79f14124fbcebca10979bacf758de5)) 215 | * new package gatsby-remark-wiki-link ([f47ea2a](https://github.com/hikerpig/gatsby-project-kb/commit/f47ea2acdd9fecf1d758df610a8e2e7726fcbf07)) 216 | 217 | 218 | ### Bug Fixes 219 | 220 | * **gatsby-remark-wiki-link:** index error ([8fd4636](https://github.com/hikerpig/gatsby-project-kb/commit/8fd4636654fc9406389c61ba52d602009a3cb700)) 221 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/README.md: -------------------------------------------------------------------------------- 1 | gatsby-theme-kb 2 | === 3 | 4 | A Gatsby theme for publishing **K**nowledge **B**ase. 5 | 6 | See the [demo and documentation](https://gatsby-project-kb.vercel.app/). 7 | 8 | [![preview](https://i.loli.net/2021/01/28/cD6QRIZqUoum4Tf.png)](https://gatsby-project-kb.vercel.app/) 9 | 10 | # Setup in your Gatsby project 11 | 12 | 1. Install dependency 13 | 14 | ``` 15 | yarn add gatsby-theme-kb 16 | ``` 17 | 18 | 2. Add these to your gatsby-config.js file: 19 | 20 | ```js 21 | module.exports = { 22 | plugins: [ 23 | { 24 | resolve: `gatsby-theme-kb`, 25 | options: { 26 | contentPath: path.resolve(__dirname, 'content'), 27 | rootNote: 'readme', 28 | wikiLinkLabelTemplate: '[[{{ refWord }}]]', 29 | getPluginMdx(defaultPluginMdx) { 30 | // customise pre-configured `gatsby-plugin-mdx`, for example: 31 | // defaultPluginMdx.options.gatsbyRemarkPlugins.push({ 32 | // resolve: 'gatsby-remark-prismjs', 33 | // }) 34 | return defaultPluginMdx 35 | }, 36 | }, 37 | }, 38 | ], 39 | }; 40 | ``` 41 | 42 | 3. Add notes to your site by adding `md` or `mdx` files in `content` directory, especially you need a `content/readme.md` file if you are using above configs. 43 | 44 | 4. Start developing your site by running `gatsby develop`. If you are using above configuration, your start url will be 'http://localhost:8000'. 45 | 46 | # Usage 47 | 48 | ## Options 49 | 50 | | Key | Default value | Description | 51 | |:----------------------:|:-------------:|:----------------------------------------------------------------------------:| 52 | | rootNote | `/readme` | Root note's name (without exts) 53 | | contentPath | | Location of local content | 54 | | extensions | `['.md', '.mdx']` | Valid content file exts | 55 | | ignore | `['.git']` | A list of file globs to ignore | 56 | | wikiLinkLabelTemplate | | A template string for specifying wiki link label, see [ options.wikiLinkLabelTemplate](# options.wikiLinkLabelTemplate) | 57 | | getPluginMdx | (defaultPluginMdx) => PluginMdx | Customise pre-configured `gatsby-plugin-mdx`, please do always return a valid gatsby plugin object | 58 | | tocTypes | `['sidebar']` | Customise the toc location, type is `false \| Array<'inline' | 'sidebar'>` | 59 | | slugifyFn | `(name) => require('slugify')(name)` | Customise the url slug of a given file name | 60 | 61 | 62 | ### options.wikiLinkLabelTemplate 63 | 64 | When a wikilink is resolved and rendered as an anchor element, the anchor label is by default `[[reference-word]]`. But some people may prefer some other forms, so here is one option for specifying the link label you want. 65 | 66 | The template string will be processed in a mustache alike manner, the variable inside `{{}}` will be replaced by real value. Currently there are some variables available: 67 | 68 | - `refWord`, the reference word inside the double brackets, usually it's the filename (without exts). 69 | - `title`, the title of the page, may be the frontmatter `title` field value, or h1 of the markdown content. 70 | 71 | For example there is page A, filename is `page-a.md`, page title is `Awesome Themes`. 72 | 73 | And in page B I write the reference as `[[page-a]]`. 74 | 75 | - config `wikiLinkLabelTemplate: '[[ {{refWord}} ]]'`, will generate `[[ page-a ]]` as link label. 76 | - config `wikiLinkLabelTemplate: '{{title}}'`, will generate `Awesome Themes` as link label. 77 | 78 | 79 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/fragments.js: -------------------------------------------------------------------------------- 1 | import { graphql } from "gatsby"; 2 | 3 | export const references = graphql` 4 | fragment GatsbyGardenReferences on Mdx { 5 | outboundReferences { 6 | contextLine 7 | targetAnchor 8 | refWord 9 | label 10 | target { 11 | ... on Mdx { 12 | body 13 | parent { 14 | id 15 | ... on File { 16 | fields { 17 | slug 18 | title 19 | } 20 | } 21 | } 22 | } 23 | } 24 | } 25 | inboundReferences { 26 | contextLine 27 | referrer { 28 | ... on Mdx { 29 | parent { 30 | id 31 | ... on File { 32 | fields { 33 | slug 34 | title 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | `; 43 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/gatsby-browser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's Browser APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.com/docs/browser-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | 9 | import './src/styles/global.css' 10 | 11 | import './src/styles/base.css' 12 | import './src/styles/theme.css' 13 | 14 | import './src/styles/tocbot.css' -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/gatsby-config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const makeSearchPlugins = require('./gatsby-node-utils/makeSearchPlugins') 3 | 4 | module.exports = function (options) { 5 | const { 6 | contentPath = 'content', 7 | mdxOtherwiseConfigured = false, 8 | ignore = ['.git'], 9 | extensions = [`.md`, `.mdx`], 10 | } = options 11 | 12 | // console.log('options', arguments) 13 | const defaultGetPluginMdx = () => { 14 | return { 15 | resolve: `gatsby-plugin-mdx`, 16 | options: { 17 | extensions, 18 | remarkPlugins: [], 19 | gatsbyRemarkPlugins: [ 20 | { 21 | resolve: 'gatsby-remark-wiki-link', 22 | options: { 23 | stripBrackets: false, 24 | stripDefinitionExts: extensions, 25 | }, 26 | }, 27 | 'gatsby-remark-double-parenthesis-link', 28 | ], 29 | }, 30 | } 31 | } 32 | 33 | const pluginMdx = mdxOtherwiseConfigured 34 | ? null 35 | : options.getPluginMdx 36 | ? options.getPluginMdx(defaultGetPluginMdx()) 37 | : defaultGetPluginMdx() 38 | 39 | // console.log('plugin mdx', pluginMdx) 40 | 41 | return { 42 | plugins: [ 43 | { 44 | resolve: `gatsby-plugin-typescript`, 45 | options: { 46 | isTSX: true, // defaults to false 47 | jsxPragma: `jsx`, // defaults to "React" 48 | allExtensions: true, // defaults to false 49 | }, 50 | }, 51 | `gatsby-plugin-react-helmet`, 52 | { 53 | resolve: 'gatsby-source-filesystem', 54 | options: { 55 | path: contentPath, 56 | name: contentPath, 57 | ignore, 58 | }, 59 | }, 60 | pluginMdx, 61 | { 62 | resolve: '@gatsby-project-kb/transformer-wiki-references', 63 | options: { 64 | contentPath: path.resolve(process.cwd(), contentPath), 65 | ignore, 66 | extensions, 67 | }, 68 | }, 69 | 'gatsby-plugin-postcss', 70 | { 71 | resolve: 'gatsby-plugin-purgecss', 72 | options: { 73 | printRejected: true, 74 | tailwind: true, 75 | purgeOnly: ['src/styles/global.css'], 76 | purgeCSSOptions: { 77 | content: [path.join(__dirname, 'src/**/*.{ts,js,jsx,tsx}')], 78 | } 79 | }, 80 | }, 81 | { 82 | resolve: 'gatsby-plugin-tocbot', 83 | options: { 84 | tocbotOptions: { 85 | contentSelector: '.topic-layout__content', 86 | collapseDepth: 5, 87 | scrollContainer: '.topic-layout__content', 88 | }, 89 | }, 90 | }, 91 | ...makeSearchPlugins(options), 92 | ], 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/gatsby-node-utils/makeSearchPlugins.js: -------------------------------------------------------------------------------- 1 | const shouldHandleFile = require('./shouldHandleFile') 2 | 3 | module.exports = function makeSearchPlugins (options) { 4 | const { contentPath } = options; 5 | 6 | if (!contentPath) { 7 | return []; 8 | } 9 | 10 | const filesPath = ` 11 | { 12 | allFile { 13 | nodes { 14 | id 15 | ext 16 | sourceInstanceName 17 | fields { 18 | title 19 | slug 20 | } 21 | childMdx { 22 | excerpt 23 | rawBody 24 | } 25 | internal { 26 | mediaType 27 | } 28 | } 29 | } 30 | } 31 | `; 32 | 33 | const query = filesPath 34 | 35 | return [ 36 | { 37 | resolve: "gatsby-plugin-local-search", 38 | options: { 39 | name: "paths", 40 | engine: "flexsearch", 41 | query, 42 | 43 | index: ["path"], 44 | 45 | store: ["id", "path", "title", "excerpt"], 46 | 47 | normalizer: ({ data }) => { 48 | let result = []; 49 | if (contentPath) { 50 | result = result.concat( 51 | data.allFile.nodes 52 | .filter((node) => shouldHandleFile(node, options)) 53 | .map((node) => ({ 54 | id: node.id, 55 | path: node.fields.slug, 56 | title: node.fields.title, 57 | // Replace weirdly formatted [ link ] in excerpt to look like wikilinks ([link]) 58 | excerpt: node.childMdx.excerpt.replace( 59 | /\[\s([\w'-]+)\s\]/gi, 60 | (_, p1) => `[${p1}]` 61 | ), 62 | })) 63 | ); 64 | } 65 | return result; 66 | }, 67 | }, 68 | }, 69 | { 70 | resolve: "gatsby-plugin-local-search", 71 | options: { 72 | name: "titles", 73 | engine: "flexsearch", 74 | query, 75 | 76 | index: ["title"], 77 | 78 | store: [], 79 | 80 | normalizer: ({ data }) => { 81 | let result = []; 82 | if (contentPath) { 83 | result = result.concat( 84 | data.allFile.nodes 85 | .filter((node) => shouldHandleFile(node, options)) 86 | .map((node) => ({ 87 | id: node.id, 88 | title: node.fields.title, 89 | })) 90 | ); 91 | } 92 | return result; 93 | }, 94 | }, 95 | }, 96 | { 97 | resolve: "gatsby-plugin-local-search", 98 | options: { 99 | name: "bodies", 100 | engine: "flexsearch", 101 | query, 102 | 103 | index: ["body"], 104 | 105 | store: [], 106 | 107 | normalizer: ({ data }) => { 108 | let result = []; 109 | if (contentPath) { 110 | result = result.concat( 111 | data.allFile.nodes 112 | .filter((node) => shouldHandleFile(node, options)) 113 | .map((node) => ({ 114 | id: node.id, 115 | body: node.childMdx.rawBody, 116 | })) 117 | ); 118 | } 119 | return result; 120 | }, 121 | }, 122 | }, 123 | ]; 124 | }; -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/gatsby-node-utils/shouldHandleFile.js: -------------------------------------------------------------------------------- 1 | module.exports = function shouldHandleFile(node, options = {}) { 2 | return ( 3 | ((options.extensions || ['.md', '.mdx']).includes(node.ext) || 4 | (options.mediaTypes || ['text/markdown', 'text/x-markdown']).includes( 5 | node.internal.mediaType 6 | )) && 7 | node.sourceInstanceName === options.contentPath 8 | ) 9 | } 10 | 11 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/gatsby-node-utils/source-nodes.js: -------------------------------------------------------------------------------- 1 | 2 | exports.sourceNodes = (api, pluginOptions) => { 3 | console.log('sourceNodes', api) 4 | } -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/gatsby-node.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | const fs = require(`fs`) 3 | const path = require(`path`) 4 | const { urlResolve } = require(`gatsby-core-utils`) 5 | const shouldHandleFile = require('./gatsby-node-utils/shouldHandleFile') 6 | const slugify = require(`slugify`) 7 | const { 8 | findTopLevelHeading, 9 | } = require(`@gatsby-project-kb/transformer-wiki-references`) 10 | 11 | // These are customizable theme options we only need to check once 12 | let contentPath 13 | let rootNoteSlug 14 | // let extensions 15 | // let mediaTypes 16 | let wikiLinkLabelTemplate 17 | let tocTypes = ['sidebar'] 18 | let slugifyFn = defaultSlugifyFn 19 | 20 | function padSlugLeading(str) { 21 | if (typeof str !== 'string') return str 22 | if (!str.startsWith('/')) str = '/' + str 23 | return str 24 | } 25 | 26 | exports.onPreBootstrap = async ({ store }, themeOptions) => { 27 | contentPath = themeOptions.contentPath 28 | rootNoteSlug = padSlugLeading(themeOptions.rootNote) || '/readme' 29 | // extensions = themeOptions.extensions || ['.md', '.mdx'] 30 | // mediaTypes = themeOptions.mediaTypes || ['text/markdown', 'text/x-markdown'] 31 | wikiLinkLabelTemplate = 32 | themeOptions.wikiLinkLabelTemplate || wikiLinkLabelTemplate 33 | 34 | if (themeOptions.slugifyFn && typeof themeOptions.slugifyFn === 'function') { 35 | slugifyFn = themeOptions.slugifyFn 36 | } 37 | 38 | if ('tocTypes' in themeOptions) { 39 | tocTypes = themeOptions.tocTypes 40 | } 41 | } 42 | 43 | function getTitle(node, content) { 44 | if ( 45 | typeof node.frontmatter === 'object' && 46 | node.frontmatter && 47 | node.frontmatter['title'] 48 | ) { 49 | return node.frontmatter['title'] 50 | } 51 | return ( 52 | findTopLevelHeading(content) || 53 | (typeof node.fileAbsolutePath === 'string' 54 | ? path.basename( 55 | node.fileAbsolutePath, 56 | path.extname(node.fileAbsolutePath) 57 | ) 58 | : '') || 59 | (typeof node.absolutePath === 'string' 60 | ? path.basename(node.absolutePath, path.extname(node.absolutePath)) 61 | : '') 62 | ) 63 | } 64 | 65 | function defaultSlugifyFn(str) { 66 | return slugify.default(str) 67 | } 68 | 69 | exports.createResolvers = ({ createResolvers }) => { 70 | const resolvers = { 71 | MdxFrontmatter: { 72 | private: { 73 | type: `Boolean`, 74 | resolve(source, args, context, info) { 75 | const { private } = source 76 | if (private == null) { 77 | return false 78 | } 79 | return private 80 | }, 81 | }, 82 | }, 83 | } 84 | createResolvers(resolvers) 85 | } 86 | 87 | exports.onCreateNode = async ({ node, actions, loadNodeContent }, options) => { 88 | const { createNodeField } = actions 89 | if (node.internal.type === `File` && shouldHandleFile(node, options)) { 90 | const slugifiedName = slugifyFn(node.name) 91 | const slug = '/' + urlResolve(path.parse(node.relativePath).dir, slugifiedName) 92 | // console.log('slug is', slug, node.relativePath) 93 | createNodeField({ 94 | node, 95 | name: `slug`, 96 | value: slug, 97 | }) 98 | createNodeField({ 99 | node, 100 | name: `title`, 101 | value: getTitle(node, await loadNodeContent(node)), 102 | }) 103 | } 104 | } 105 | 106 | exports.createPages = async ({ graphql, actions }, options) => { 107 | const { createPage } = actions 108 | 109 | if (contentPath) { 110 | const result = await graphql( 111 | ` 112 | { 113 | allFile { 114 | nodes { 115 | id 116 | sourceInstanceName 117 | ext 118 | internal { 119 | mediaType 120 | } 121 | fields { 122 | slug 123 | } 124 | childMdx { 125 | id 126 | frontmatter { 127 | private 128 | } 129 | outboundReferences { 130 | refWord 131 | label 132 | target { 133 | ... on Mdx { 134 | id 135 | slug 136 | } 137 | } 138 | } 139 | } 140 | } 141 | } 142 | allMdx { 143 | nodes { 144 | id 145 | slug 146 | outboundReferences { 147 | refWord 148 | label 149 | target { 150 | ... on Mdx { 151 | id 152 | slug 153 | } 154 | } 155 | } 156 | parent { 157 | ... on File { 158 | id 159 | } 160 | } 161 | } 162 | } 163 | } 164 | ` 165 | ) 166 | 167 | if (result.errors) { 168 | console.log(result.errors) 169 | throw new Error(`Could not query notes`, result.errors) 170 | } 171 | 172 | const TopicTemplate = require.resolve( 173 | options.topicTemplate || `./src/templates/Topic` 174 | ) 175 | 176 | const mdxNodeMap = new Map() 177 | result.data.allMdx.nodes.forEach((mdxNode) => { 178 | mdxNodeMap.set(mdxNode.id, mdxNode) 179 | }) 180 | 181 | const getContextByNode = (n) => { 182 | const refWordMdxSlugDict = {} 183 | 184 | const enrichRefDetails = (mdxNode) => { 185 | if (mdxNode && mdxNode.outboundReferences) { 186 | mdxNode.outboundReferences.forEach((ref) => { 187 | const refMdxNode = mdxNodeMap.get(ref.target.id) 188 | // console.log( 189 | // 'refMdxNode exists: ', 190 | // Boolean(refMdxNode), 191 | // ref.target.id 192 | // ) 193 | if (refMdxNode) { 194 | // console.log(`${ref.refWord}: ${refMdxNode.slug}`) 195 | if (refWordMdxSlugDict[ref.refWord]) { 196 | return // prevent cycles 197 | } 198 | refWordMdxSlugDict[ref.refWord] = refMdxNode.slug 199 | enrichRefDetails(refMdxNode) 200 | } 201 | }) 202 | } 203 | } 204 | 205 | enrichRefDetails(n.childMdx) 206 | 207 | return { 208 | id: n.id, 209 | wikiLinkLabelTemplate, 210 | refWordMdxSlugDict, 211 | tocTypes, 212 | } 213 | } 214 | 215 | const localFiles = result.data.allFile.nodes 216 | .filter((node) => shouldHandleFile(node, options)) 217 | .filter((x) => x.childMdx.frontmatter.private !== true) 218 | 219 | localFiles.forEach((node) => { 220 | createPage({ 221 | path: node.fields.slug, 222 | component: TopicTemplate, 223 | context: getContextByNode(node), 224 | }) 225 | }) 226 | 227 | if (rootNoteSlug) { 228 | const root = localFiles.find((node) => node.fields.slug === rootNoteSlug) 229 | // console.log('root is', root, 'rootNoteSlug', rootNoteSlug) 230 | if (root) { 231 | createPage({ 232 | path: '/', 233 | component: TopicTemplate, 234 | context: getContextByNode(root), 235 | }) 236 | } 237 | } 238 | } 239 | } 240 | 241 | exports.onCreateWebpackConfig = ({ actions }) => { 242 | actions.setWebpackConfig({ 243 | resolve: { 244 | alias: { 245 | path: require.resolve('path-browserify'), 246 | }, 247 | fallback: { 248 | fs: false, 249 | }, 250 | }, 251 | }) 252 | } 253 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.com/docs/ssr-apis/ 5 | */ 6 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-theme-kb", 3 | "description": "A Gatsby theme for publishing Knowledge Base.", 4 | "version": "0.9.4", 5 | "dependencies": { 6 | "@gatsby-project-kb/transformer-wiki-references": "^0.3.1", 7 | "@mdx-js/mdx": "^1.6.22", 8 | "@mdx-js/react": "^1.6.22", 9 | "@reecelucas/react-use-hotkeys": "^1.3.1", 10 | "@tippyjs/react": "^4.2.6", 11 | "autoprefixer": "^10.4.0", 12 | "classnames": "^2.3.1", 13 | "downshift": "^6.1.7", 14 | "flexsearch": "^0.6.32", 15 | "gatsby-plugin-local-search": "^2.0.1", 16 | "gatsby-plugin-mdx": "^3.4.0", 17 | "gatsby-plugin-postcss": "^5.4.0", 18 | "gatsby-plugin-purgecss": "^6.1.0", 19 | "gatsby-plugin-react-helmet": "^5.4.0", 20 | "gatsby-plugin-tocbot": "^0.1.0", 21 | "gatsby-plugin-typescript": "^4.4.0", 22 | "gatsby-react-router-scroll": "^5.4.0", 23 | "gatsby-remark-double-parenthesis-link": "^0.1.5", 24 | "gatsby-remark-wiki-link": "^0.4.1", 25 | "gatsby-source-filesystem": "^4.4.0", 26 | "note-graph": "^0.3.0", 27 | "path-browserify": "^1.0.1", 28 | "postcss": "^8.4.5", 29 | "prop-types": "^15.7.2", 30 | "react": "^17.0.2", 31 | "react-dom": "^17.0.2", 32 | "react-helmet": "^6.1.0", 33 | "tailwindcss": "^2.2.9", 34 | "use-breakpoint": "^3.0.0", 35 | "use-dark-mode": "^2.3.1" 36 | }, 37 | "devDependencies": { 38 | "@types/node": "^17.0.1", 39 | "prettier": "2.5.1", 40 | "typescript": "^4.5.4" 41 | }, 42 | "peerDependencies": { 43 | "gatsby": "^4.4.0" 44 | }, 45 | "keywords": [ 46 | "gatsby", 47 | "gatsby-plugin", 48 | "gatsby-theme", 49 | "knowledge-base", 50 | "bidirectional-link", 51 | "note-graph" 52 | ], 53 | "author": { 54 | "name": "hikerpig", 55 | "url": "https://github.com/hikerpig" 56 | }, 57 | "license": "MIT", 58 | "scripts": { 59 | "build": "gatsby build", 60 | "develop": "gatsby develop", 61 | "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"", 62 | "start": "npm run develop", 63 | "serve": "gatsby serve", 64 | "clean": "gatsby clean", 65 | "typecheck": "tsc --noEmit", 66 | "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1" 67 | }, 68 | "repository": { 69 | "type": "git", 70 | "url": "https://github.com/hikerpig/gatsby-project-kb.git" 71 | }, 72 | "bugs": { 73 | "url": "https://github.com/hikerpig/gatsby-project-kb/issues" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/src/components/DarkModeToggle/dark-mode-toggle.css: -------------------------------------------------------------------------------- 1 | /* This is based off a codepen! Much appreciated to: https://codepen.io/aaroniker/pen/KGpXZo */ 2 | .dark-mode-toggle { 3 | cursor: pointer; 4 | display: flex; 5 | } 6 | .dark-mode-toggle input { 7 | display: none; 8 | } 9 | .dark-mode-toggle input + div { 10 | border-radius: 50%; 11 | width: 20px; 12 | height: 20px; 13 | position: relative; 14 | box-shadow: inset 5px -5px 0 0 #fff; 15 | transform: scale(1) rotate(-2deg); 16 | transition: box-shadow 0.5s ease 0s, transform 0.4s ease 0.1s; 17 | } 18 | .dark-mode-toggle input + div:before { 19 | content: ""; 20 | width: inherit; 21 | height: inherit; 22 | border-radius: inherit; 23 | position: absolute; 24 | left: 0; 25 | top: 0; 26 | transition: background 0.3s ease; 27 | } 28 | .dark-mode-toggle input + div:after { 29 | content: ""; 30 | width: 4px; 31 | height: 4px; 32 | border-radius: 50%; 33 | margin: -2px 0 0 -2px; 34 | position: absolute; 35 | top: 50%; 36 | left: 50%; 37 | box-shadow: 0 -11px 0 var(--kb-text-color), 0 11px 0 var(--kb-text-color), 11px 0 0 var(--kb-text-color), 38 | -11px 0 0 var(--kb-text-color), 8px 8px 0 var(--kb-text-color), -8px 8px 0 var(--kb-text-color), 39 | 8px -8px 0 var(--kb-text-color), -8px -8px 0 var(--kb-text-color); 40 | transform: scale(0); 41 | transition: all 0.3s ease; 42 | } 43 | 44 | .dark-mode-toggle input:checked + div { 45 | box-shadow: inset 32px -32px 0 0 #fff; 46 | transform: scale(0.5) rotate(0deg); 47 | transition: transform 0.3s ease 0.1s, box-shadow 0.2s ease 0s; 48 | } 49 | .dark-mode-toggle input:checked + :before { 50 | background: var(--kb-text-color); 51 | transition: background 0.3s ease 0.1s; 52 | } 53 | .dark-mode-toggle input:checked + :after { 54 | transform: scale(1.5); 55 | transition: transform 0.5s ease 0.15s; 56 | } 57 | .dark-mode-toggle__hint { 58 | margin-left: 5px; 59 | } -------------------------------------------------------------------------------- /packages/gatsby-theme-kb/src/components/DarkModeToggle/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import useDarkMode from 'use-dark-mode' 3 | 4 | import './dark-mode-toggle.css' 5 | 6 | const DarkModeToggle = (props: { showHint?: boolean}) => { 7 | const { value: isDark, toggle: toggleDarkMode } = useDarkMode(false) 8 | const hint = isDark ? 'Activate light mode' : 'Activate dark mode' 9 | 10 | return ( 11 |