Repository: PaulieScanlon/gatsby-theme-terminal Branch: main Commit: d842c15744b3 Files: 86 Total size: 148.0 KB Directory structure: gitextract_xb6i9ro3/ ├── .commitlintrc.js ├── .github/ │ └── FUNDING.yml ├── .gitignore ├── .husky/ │ ├── commit-msg │ └── pre-commit ├── .prettierignore ├── .prettierrc.js ├── @pauliescanlon/ │ └── gatsby-theme-terminal/ │ ├── README.md │ ├── gatsby-browser.js │ ├── gatsby-config.js │ ├── gatsby-node.js │ ├── gatsby-ssr.js │ ├── index.js │ ├── package.json │ └── src/ │ ├── components/ │ │ ├── logo/ │ │ │ ├── index.js │ │ │ └── logo.js │ │ ├── main/ │ │ │ ├── index.js │ │ │ └── main.js │ │ ├── nav/ │ │ │ ├── index.js │ │ │ └── nav.js │ │ ├── page-element/ │ │ │ ├── index.js │ │ │ └── page-element.js │ │ ├── seo/ │ │ │ ├── index.js │ │ │ └── seo.js │ │ ├── site-metadata/ │ │ │ ├── index.js │ │ │ └── site-metadata.js │ │ ├── source-article/ │ │ │ ├── index.js │ │ │ └── source-article.js │ │ ├── source-days/ │ │ │ ├── index.js │ │ │ └── source-days.js │ │ ├── source-list/ │ │ │ ├── index.js │ │ │ └── source-list.js │ │ ├── source-months/ │ │ │ ├── index.js │ │ │ └── source-months.js │ │ ├── source-tags/ │ │ │ ├── index.js │ │ │ └── source-tags.js │ │ └── source-words/ │ │ ├── index.js │ │ └── source-words.js │ ├── context/ │ │ └── index.js │ ├── data/ │ │ ├── index.js │ │ ├── use-config.js │ │ ├── use-dates.js │ │ ├── use-navigation.js │ │ ├── use-source.js │ │ ├── use-tags.js │ │ └── use-words.js │ ├── gatsby-plugin-theme-ui/ │ │ └── index.js │ ├── layouts/ │ │ ├── page-layout.js │ │ └── source-layout.js │ ├── pages/ │ │ └── 404.js │ └── utils/ │ └── index.js ├── README.md ├── copy-readme.js ├── demo/ │ ├── LICENSE │ ├── README.md │ ├── gatsby-browser.js │ ├── gatsby-config.js │ ├── gatsby-node.js │ ├── gatsby-ssr.js │ ├── package.json │ └── src/ │ ├── @pauliescanlon/ │ │ └── gatsby-theme-terminal/ │ │ └── components/ │ │ └── Logo/ │ │ └── Logo.js │ ├── _temp/ │ │ ├── source-days.mdx │ │ ├── source-list.mdx │ │ ├── source-months.mdx │ │ ├── source-tags.mdx │ │ └── source-words.mdx │ ├── pages/ │ │ ├── components.mdx │ │ ├── index.mdx │ │ ├── markdown.mdx │ │ ├── posts.mdx │ │ ├── projects.mdx │ │ └── theme-ui-components.mdx │ ├── posts/ │ │ ├── 2019/ │ │ │ ├── 03/ │ │ │ │ └── a-pinned-post.mdx │ │ │ └── post-2.mdx │ │ ├── 2020/ │ │ │ ├── 01/ │ │ │ │ └── post-3.mdx │ │ │ ├── 02/ │ │ │ │ ├── post-4.mdx │ │ │ │ └── post-5.mdx │ │ │ └── 04/ │ │ │ └── private.mdx │ │ ├── 2021/ │ │ │ ├── local-image-post.mdx │ │ │ └── remote-image-post.mdx │ │ └── post-1.mdx │ └── projects/ │ ├── 2019/ │ │ └── project-2.mdx │ ├── 2020/ │ │ └── 01/ │ │ └── project-3.mdx │ └── project-1.mdx ├── netlify.toml └── package.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .commitlintrc.js ================================================ module.exports = { extends: ['@commitlint/config-conventional'], } ================================================ FILE: .github/FUNDING.yml ================================================ github: [pauliescanlon] ko_fi: pauliescanlon ================================================ FILE: .gitignore ================================================ wip-readme.md demo/src/pages/source-days.mdx demo/src/pages/source-list.mdx demo/src/pages/source-months.mdx demo/src/pages/source-tags.mdx demo/src/pages/source-words.mdx # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # nyc test coverage .nyc_output # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # Typescript v1 declaration files typings/ # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # dotenv environment variables file .env # gatsby files .cache/ public # Mac files .DS_Store # Yarn yarn-error.log .pnp/ .pnp.js # Yarn Integrity file .yarn-integrity .netlify/ ================================================ FILE: .husky/commit-msg ================================================ #!/bin/sh . "$(dirname "$0")/_/husky.sh" npx commitlint --edit ================================================ FILE: .husky/pre-commit ================================================ #!/bin/sh . "$(dirname "$0")/_/husky.sh" npm run prettier ================================================ FILE: .prettierignore ================================================ demo/.cache demo/public ================================================ FILE: .prettierrc.js ================================================ module.exports = { semi: false, trailingComma: 'all', singleQuote: true, printWidth: 120, tabWidth: 2, proseWrap: 'always', } ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/README.md ================================================ gatsby-theme-termninal main image ## gatsby-theme-terminal Gatsby Theme Terminal aims to be a **zero component theme**. It provides _data_ components to aid in the abstraction of presentational and data layers which together provide the most flexibility The theme handles the data but how it's displayed is up to you! You can create any page layout or component combination you like using your own components or components provided by [theme-ui/components](https://theme-ui.com/components) ## 👀 Preview - [Live Demo](https://gatsbythemeterminal.gatsbyjs.io/) ## 🚀 Getting started To help you get started you can either clone the starter [gatsby-starter-terminal](https://github.com/PaulieScanlon/gatsby-starter-terminal) or read the below. ### Install ``` npm install @pauliescanlon/gatsby-theme-terminal ``` ### Install Peer Dependencies ``` npm install @mdx-js/mdx @mdx-js/react gatsby gatsby-plugin-mdx gatsby-source-filesystem react react-dom ``` ## Setup ### gatsby-config.js Add the `siteMetaData` and `@pauliescanlon/gatsby-theme-terminal` to your `gatsby-config.js` ``` // gatsby-config.js module.exports = { siteMetadata: { name: "Your blog title", description: "I like tech", keywords: ["tech", "blog", "boop"], siteUrl: 'https://gatsby-theme-terminal.netlify.com', siteImage: 'name-of-open-graph-image.jpg', // pop an image in the static folder to use it as the og:image, profileImage: 'name-of-profile-image.jpg' lang: `eng`, config: { sidebarWidth: 240 // optional, }, }, plugins: ['@pauliescanlon/gatsby-theme-terminal'] } ``` ### directory structure To add pages create `.mdx` files in the `src/pages` directory. You need at least one file called `index.mdx` located at `src/pages` or you'll see a GraphQL error. ``` |-- src |-- pages |-- index.mdx |-- about.mdx |-- contact.mdx ``` ### frontmatter setup #### Pages Pages must include `navigationLabel` in the `frontmatter` ``` // src/pages/about.mdx --- navigationLabel: About --- # About This is about page ``` #### Theme options Additional `.mdx` can be sourced from _anywhere_ outside the `pages` directory but you need to tell the theme where to source these files from. Use the `source` option in `gatsby-config.js` ``` // gatsby-config.js ... plugins: [ { resolve: `@pauliescanlon/gatsby-theme-terminal`, options: { source: [ { name: "posts", dir: "posts", }, { name: "projects", dir: "projects", }, ] // can be an object or array of objects }, }, ], } ``` Then create the relevant files and directories ``` |-- src |-- pages ... |-- posts |--2020 |--02 |-- some-post.mdx |-- featuredImage: markus-spiske-466ENaLuhLY-unsplash.jpg |-- markus-spiske-FXFz-sW0uwo-unsplash.jpg |-- projects |-- some-project.mdx ``` Any file that is _not_ sourced from `pages` can contain any of the following `frontmatter` but a `title` is required, this is how the theme distinguishes between pages and other `.mdx` files ``` // src/posts/2020/02/some-post.mdx --- title: Some Post tags: ["JavaScript", "React", "GatsbyJs", "HTML", "CSS", "theme-ui"] date: 2020-01-01 dateModified: 20-20-2020 author: Paul Scanlon status: draft // => means it won't be rendered isPrivate: // => it will be rendered but you can use this prop as a filter url: "https://example.com" // => could be an external url misc: "Ahoy" // => use how you wish pinned: false // => Could be used as a filter for pinned posts featuredImage: markus-spiske-466ENaLuhLY-unsplash.jpg featuredImageUrl: https://via.placeholder.com/936x528 embeddedImages: - markus-spiske-FXFz-sW0uwo-unsplash.jpg embeddedImageUrls: - https://via.placeholder.com/468x264 --- ``` ### Embedded Images By using the The `` component from `gatsby-plugin-image` you can pass the image data queried by GraphQL and pass it on via the `image` prop The `gatsbyImageData`, data is available via `props.embedded.image(n)` ``` ``` You can also use the Theme UI `` component by passing it a `src` ``` ``` `image1` in this example would be `markus-spiske-FXFz-sW0uwo-unsplash.jpg` EmbeddedImages can also be sourced from a remote url, in this case use the `` component and pass it the same props ``` ``` ### markdown The theme supports the complete markdown spec and you can see how to use markdown in the [demo](https://gatsbythemeterminal.gatsbyjs.io/markdown/) ### theme-ui/components The theme supports _all_ the components provided by [theme-ui/components](https://theme-ui.com/components) and you can see in the [demo](https://gatsbythemeterminal.gatsbyjs.io/theme-ui-components/) how they are used. ### gatsby-theme-terminal/components The theme also comes with it's own components _but_... These are purely to provide access to the source nodes. What you choose to render is completely up to you! For example to display a list of _all_ files sourced from the `source` theme option you _could_ do something like this. This component can be used in ANY `.mdx` file 😎 ```javascript {(source) => (
    {source.map((edge, index) => { const { frontmatter: { title }, } = edge.node return
  • {title}
  • })}
)}
``` You can see more about how to use the theme components in the [demo](https://gatsbythemeterminal.gatsbyjs.io/components/) ### Component Shadowing There is very little to shadow because almost everything is exposed by the components but you might want to add your own logo. To do this create the following directories `@pauliescanlon/gatsby-theme-terminal/components/Logo` in the `src` directory of your project and then create a `Logo.js` file. You can do anything you like in here. ``` |-- src |-- @pauliescanlon |-- gatsby-theme-terminal |-- components |-- Logo |-- Logo.js ``` If you would like to customize any part of the theme you can do so by shadowing the theme file. To do this create the following directory `src/gatsby-plugin-theme-ui` and then create an `index.js` ```javascript // src/gatsby-plugin-theme-ui/index.js import baseTheme from '@pauliescanlon/gatsby-theme-terminal/src/gatsby-plugin-theme-ui' export default { ...baseTheme, colors: { ...baseTheme.colors, primary: '#FF4081', secondary: '#03A9F4', success: '#FFEB3B', background: '#232323', surface: '#393939', }, } ``` ### favicon favicon(s) need to be saved in `static/images` and named `favicon-16x16.png` and `favicon-32x32.png` along with an `.icon` file called `favicon.ico` If you're using **gatsby-theme-terminal** in your project i'd love to hear from you [@pauliescanlon](https://twitter.com/PaulieScanlon) [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/P5P31B7G8) ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/gatsby-browser.js ================================================ const React = require('react') const { PageElement } = require('./src/components/page-element') const anchorScroll = (location) => { const anchor = document.querySelectorAll(`a[href="${location.hash}"]`)[0] if (location && location.hash && anchor) { const item = document.querySelectorAll(`a[href="${location.hash}"]`)[0].offsetTop const mainNavHeight = document.querySelector(`header`).offsetHeight setTimeout(() => { window.scrollTo({ top: item - mainNavHeight, behavior: 'smooth', }) }, 50) } } exports.onRouteUpdate = ({ location }) => { anchorScroll(location) return true } exports.wrapPageElement = ({ element }) => { return {element} } ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/gatsby-config.js ================================================ const path = require('path') module.exports = (themeOptions) => { const { source } = themeOptions let filesystemSources = [] if (source) { const sourceFilesystemOption = (item) => { if (source) { return { resolve: `gatsby-source-filesystem`, options: { name: `${item.name}`, path: path.resolve(`src/${item.dir}`), }, } } } if (Array.isArray(source)) { for (let item of source) { filesystemSources.push(sourceFilesystemOption(item)) } } else { filesystemSources.push(sourceFilesystemOption(source)) } } return { siteMetadata: { name: ``, description: ``, keywords: [], siteUrl: ``, siteImage: ``, profileImage: ``, lang: ``, config: { sidebarWidth: 260, }, }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-plugin-image`, `gatsby-transformer-sharp`, { resolve: `gatsby-plugin-sharp`, options: { defaults: { quality: 70, formats: ['auto', 'webp', 'avif'], placeholder: 'blurred', }, }, }, `gatsby-plugin-theme-ui`, { resolve: `gatsby-plugin-mdx`, options: { defaultLayouts: { default: require.resolve(`./src/layouts/page-layout.js`), }, }, }, // Demo pages { resolve: 'gatsby-source-filesystem', options: { name: 'pages', path: path.resolve(`src/pages`), }, }, // Demo 'src/whatever' the user has defined in options.source ...filesystemSources, ], } } ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/gatsby-node.js ================================================ const { createFilePath, createRemoteFileNode } = require('gatsby-source-filesystem') const path = require('path') exports.createSchemaCustomization = async ({ actions }) => { const { createTypes } = actions createTypes(` type Mdx implements Node { frontmatter: Frontmatter featuredImageUrl: File @link(from: "fields.featuredImageUrl") embeddedImageUrls: [File] @link(from: "fields.embeddedImageUrls") } type Frontmatter @dontInfer { title: String navigationLabel: String tags: [String] date: String dateModified: String author: String status: String isPrivate: Boolean url: String misc: String pinned: Boolean featuredImage: File @fileByRelativePath featuredImageUrl: String embeddedImages: [File] @fileByRelativePath embeddedImageUrls: [String] } `) // Logs out all typeDefs // actions.printTypeDefinitions({ path: './typeDefs.txt' }) } exports.onCreateNode = async ( { node, actions: { createNodeField, createNode }, getNode, store, cache, createNodeId }, themeOptions, ) => { const { source } = themeOptions if (node.internal.type === 'Mdx') { let basePath = '' if (Array.isArray(source)) { source.map((item) => { const { name, dir } = item if (node.fileAbsolutePath.includes(name)) { basePath = `/${dir}` } }) } else { if (node.fileAbsolutePath.includes(source.name)) { basePath = `/${source.dir}` } } const value = createFilePath({ node, getNode }) await createNodeField({ node, name: 'slug', value: node.frontmatter.navigationLabel ? value : `${basePath}${value}`, }) if (node.frontmatter.featuredImageUrl) { let featuredImageUrl = await createRemoteFileNode({ url: node.frontmatter.featuredImageUrl, parentNodeId: node.id, createNode, createNodeId, cache, store, }) if (featuredImageUrl) { createNodeField({ node, name: 'featuredImageUrl', value: featuredImageUrl.id }) } } if (node.frontmatter.embeddedImageUrls) { let embeddedImageUrls = await Promise.all( node.frontmatter.embeddedImageUrls.map((url) => { return createRemoteFileNode({ url, parentNodeId: node.id, createNode, createNodeId, cache, store, }) }), ) if (embeddedImageUrls) { createNodeField({ node, name: 'embeddedImageUrls', value: embeddedImageUrls.map((embeddedImageUrl) => { return embeddedImageUrl.id }), }) } } } } exports.createPages = async ({ graphql, actions, reporter }, themeOptions) => { const { source } = themeOptions const { createPage } = actions if (!source) return const result = await graphql(` query { allMdx( filter: { frontmatter: { status: { ne: "draft" }, navigationLabel: { eq: null } } } sort: { order: DESC, fields: [frontmatter___date] } ) { edges { node { id frontmatter { title navigationLabel } fields { slug } } } } } `) if (result.errors) { reporter.panicOnBuild('🚨 ERROR: Loading "createPages" query') } const data = result.data.allMdx.edges data.forEach(({ node }) => { createPage({ path: node.fields.slug, component: path.join(__dirname, `src/layouts/source-layout.js`), context: { id: node.id, }, }) }) } ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/gatsby-ssr.js ================================================ const React = require('react') const { PageElement } = require('./src/components/page-element') exports.wrapPageElement = ({ element }) => { return {element} } ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/index.js ================================================ // Data Components export { Main } from './src/components/main' // Data Components export { SourceDays } from './src/components/source-days' export { SourceList } from './src/components/source-list' export { SourceMonths } from './src/components/source-months' export { SourceTags } from './src/components/source-tags' export { SourceWords } from './src/components/source-words' // Data export { useConfig } from './src/data/use-config' export { useNavigation } from './src/data/use-navigation' export { useDates } from './src/data/use-dates' export { useTags } from './src/data/use-tags' export { useWords } from './src/data/use-words' export { useSource } from './src/data/use-source' ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/package.json ================================================ { "name": "@pauliescanlon/gatsby-theme-terminal", "description": "A zero component Gatsby theme for developers", "version": "2.0.0", "author": "Paul Scanlon ", "dependencies": { "@emotion/react": "^11.4.0", "@theme-ui/color": "^0.11.3", "@theme-ui/prism": "^0.11.3", "date-fns": "^2.23.0", "gatsby-plugin-image": "^2.0.0", "gatsby-plugin-mdx": "^3.0.0", "gatsby-plugin-react-helmet": "^5.0.0", "gatsby-plugin-sharp": "^4.0.0", "gatsby-plugin-theme-ui": "^0.11.3", "gatsby-source-filesystem": "^4.0.0", "gatsby-transformer-sharp": "^4.0.0", "husky": "^7.0.1", "prettier": "^2.3.2", "prop-types": "15.7.2", "react-helmet": "^6.1.0", "theme-ui": "^0.11.3" }, "peerDependencies": { "@mdx-js/mdx": "^1.6.22", "@mdx-js/react": "^1.6.22", "gatsby": "^4.0.0", "gatsby-plugin-mdx": "^3.0.0", "gatsby-source-filesystem": "^4.0.0", "react": "^17.0.0", "react-dom": "^17.0.0" }, "keywords": [ "gatsby", "gatsby-theme", "gatsby-plugin" ], "license": "MIT", "scripts": { "build": "gatsby build", "develop": "gatsby develop", "format": "prettier --write \"**/*.{js,jsx,json}\"", "start": "npm run develop", "serve": "gatsby serve", "clean": "gatsby clean", "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1", "publish": "npm login" }, "repository": { "type": "git", "url": "git+https://github.com/pauliescanlon/gatsby-theme-terminal.git" }, "bugs": { "url": "https://github.com/pauliescanlon/gatsby-theme-terminal/issues" }, "homepage": "https://gatsby-theme-terminal.netlify.com/", "main": "index.js" } ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/src/components/logo/index.js ================================================ export { Logo } from './logo' ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/src/components/logo/logo.js ================================================ /** @jsx jsx */ import { jsx } from 'theme-ui' export const Logo = () => ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/src/components/main/index.js ================================================ export { Main } from './main' ================================================ FILE: @pauliescanlon/gatsby-theme-terminal/src/components/main/main.js ================================================ import React, { Fragment, useContext } from 'react' import PropTypes from 'prop-types' import { MDXProvider } from '@mdx-js/react' import Prism from '@theme-ui/prism' import { Link as GatsbyLink } from 'gatsby' import { Context } from '../../context' import { Nav } from '../nav' import { useConfig } from '../../data' // Mdx components import * as themeUiComponents from 'theme-ui' import { GatsbyImage, getImage } from 'gatsby-plugin-image' import { Container, Box, Close, Image, MenuButton, Link } from 'theme-ui' import { transparentize } from '@theme-ui/color' // Theme specific components import { Logo } from '../logo' import { SiteMetaData } from '../site-metadata' import { SourceList } from '../source-list' import { SourceDays } from '../source-days' import { SourceMonths } from '../source-months' import { SourceWords } from '../source-words' import { SourceTags } from '../source-tags' const components = { a: ({ href, children }) => { // If it's an external url use Link and target _blank if (href.match(/^(http|https):/g)) { return ( {children} ) } // if it's a # use Link which will fires an anchorScroll in gatsby-browser if (href.match(/#/gi)) { return {children} } // if it's anything else use GatsbyLink return ( {children} ) }, pre: ({ children }) => {children}, code: Prism, Fragment, SiteMetaData, SourceList, SourceDays, SourceMonths, SourceWords, SourceTags, GatsbyImage: (props) => , ...themeUiComponents, } export const Main = ({ children }) => { const { site: { siteMetadata: { config: { sidebarWidth }, }, }, } = useConfig() const { state: { isNavOpen }, dispatch, } = useContext(Context) return ( `${theme.borderWidths[1]}px solid ${theme.colors.surface}`, display: 'flex', justifyContent: 'space-between', height: (theme) => `${theme.space[5]}px`, ml: [0, 0, 0, sidebarWidth], overflow: 'hidden', position: 'fixed', px: [3, 4], width: ['100%', '100%', '100%', `calc(100% - ${sidebarWidth}px)`], zIndex: 997, }} > dispatch({ type: 'openNav' })} /> `${theme.borderWidths[1]}px solid ${theme.colors.surface}`, height: '100%', left: [ `${isNavOpen ? 0 : `-${sidebarWidth}px`}`, `${isNavOpen ? 0 : `-${sidebarWidth}px`}`, `${isNavOpen ? 0 : `-${sidebarWidth}px`}`, 0, ], transition: '.3s ease-in-out left', position: 'relative', }} >