diff --git a/.eslintrc.js b/.eslintrc.js index b973970c9..9c02c7870 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -67,7 +67,7 @@ module.exports = { "import/extensions": 0, "react/jsx-one-expression-per-line": 0, "react/no-danger": 0, - "react/display-name": 1, + "react/display-name": 0, "react/react-in-jsx-scope": 0, "react/jsx-uses-react": 1, "react/forbid-prop-types": 0, diff --git a/plop-templates/theme/gatsby-config.js.hbs b/plop-templates/theme/gatsby-config.js.hbs index b2bfe76fe..6649d3c85 100644 --- a/plop-templates/theme/gatsby-config.js.hbs +++ b/plop-templates/theme/gatsby-config.js.hbs @@ -8,7 +8,6 @@ module.exports = themeOptions => ({ siteLanguage: `en`, siteImage: `/banner.jpg`, author: `@lekoarts_de`, - basePath, }, plugins: [ `gatsby-plugin-typescript`, diff --git a/themes/gatsby-theme-emma-core/.npmignore b/themes/gatsby-theme-emma-core/.npmignore new file mode 100644 index 000000000..780a6c548 --- /dev/null +++ b/themes/gatsby-theme-emma-core/.npmignore @@ -0,0 +1,17 @@ +.cache +node_modules +public +projects + +.idea +.vscode +.DS_Store + +index.d.ts +types.ts + +__tests__ + + +tsconfig.json +jest.config.js \ No newline at end of file diff --git a/themes/gatsby-theme-emma-core/README.md b/themes/gatsby-theme-emma-core/README.md new file mode 100644 index 000000000..ba321a1ac --- /dev/null +++ b/themes/gatsby-theme-emma-core/README.md @@ -0,0 +1,79 @@ +

+ + Gatsby Theme + +

+

+ @lekoarts/gatsby-theme-emma-core +

+ +

+ + @lekoarts/gatsby-theme-emma-core is released under the MIT license. + + + Current npm package version. + + + Downloads per month on npm. + + + Total downloads on npm. + + PRs welcome! + + Follow @lekoarts_de + +

+ +Core Theme for [`@lekoarts/gatsby-theme-emma`](https://github.com/LekoArts/gatsby-themes/tree/master/themes/gatsby-theme-emma). This theme implements the `Project` and `Page` node interfaces and exports templates (+ queries) which you can shadow. + +[**Demo Website**](https://emma.lekoarts.de) ([Source Code](https://github.com/LekoArts/gatsby-starter-portfolio-emma)) + +Also be sure to checkout other [Free & Open Source Gatsby Themes](https://themes.lekoarts.de) + +## Installation + +```sh +npm install @lekoarts/gatsby-theme-emma-core +``` + +## Usage + +### Theme options + +| Key | Default Value | Description | +| -------------- | ------------------ | --------------------------------------------------------------------------------------------------------- | +| `basePath` | `/` | Root url for the theme | +| `projectsPath` | `content/projects` | Location of projects | +| `pagesPath` | `content/pages` | Location of additional pages (optional) | +| `mdx` | `true` | Configure `gatsby-plugin-mdx` (if your website already is using the plugin pass `false` to turn this off) | + +The usage of `content/pages` is optional. If no page/MDX file is found the navigation will be hidden. + +#### Example usage + +```js +// gatsby-config.js +module.exports = { + plugins: [ + { + resolve: `@lekoarts/gatsby-theme-emma-core`, + options: { + // basePath defaults to `/` + basePath: `/sideproject`, + // projectsPath defaults to `content/projects` + projectsPath: `content/cool-projects` + } + } + ] +}; +``` + +## 🌟 Supporting me + +Thanks for using this project! I'm always interested in seeing what people do with my projects, so don't hesitate to tag me on [Twitter](https://twitter.com/lekoarts_de) and share the project with me. + +Please star this project, share it on Social Media or consider supporting me on [Patreon](https://www.patreon.com/lekoarts)! + +If you want to hire me for **contract/freelance work**, you can do so! [Get in touch with me!](https://www.lekoarts.de/en/contact) diff --git a/themes/gatsby-theme-emma-core/gatsby-config.js b/themes/gatsby-theme-emma-core/gatsby-config.js new file mode 100644 index 000000000..c2f2d6fe8 --- /dev/null +++ b/themes/gatsby-theme-emma-core/gatsby-config.js @@ -0,0 +1,66 @@ +const withDefaults = require(`./utils/default-options`) + +module.exports = themeOptions => { + const options = withDefaults(themeOptions) + const { mdx = true } = themeOptions + + return { + siteMetadata: { + siteTitle: `Emma`, + siteTitleAlt: `Emma - @lekoarts/gatsby-theme-emma`, + siteHeadline: `Emma - Gatsby Theme from @lekoarts`, + siteUrl: `https://emma.lekoarts.de`, + siteDescription: `Minimalistic portfolio with full-width grid, page transitions, support for additional MDX pages, and a focus on large images`, + siteLanguage: `en`, + siteImage: `/banner.jpg`, + author: `@lekoarts_de`, + basePath: options.basePath, + projectsPath: options.projectsPath, + pagesPath: options.pagesPath, + }, + plugins: [ + { + resolve: `gatsby-source-filesystem`, + options: { + name: options.projectsPath, + path: options.projectsPath, + }, + }, + { + resolve: `gatsby-source-filesystem`, + options: { + name: options.pagesPath, + path: options.pagesPath, + }, + }, + mdx && { + resolve: `gatsby-plugin-mdx`, + options: { + gatsbyRemarkPlugins: [ + { + resolve: `gatsby-remark-images`, + options: { + maxWidth: 820, + quality: 90, + linkImagesToOriginal: false, + }, + }, + ], + plugins: [ + { + resolve: `gatsby-remark-images`, + options: { + maxWidth: 820, + quality: 90, + linkImagesToOriginal: false, + }, + }, + ], + }, + }, + `gatsby-transformer-sharp`, + `gatsby-plugin-sharp`, + `gatsby-plugin-typescript`, + ].filter(Boolean), + } +} diff --git a/themes/gatsby-theme-emma/gatsby-node.js b/themes/gatsby-theme-emma-core/gatsby-node.js similarity index 53% rename from themes/gatsby-theme-emma/gatsby-node.js rename to themes/gatsby-theme-emma-core/gatsby-node.js index 8b2334d21..d9f966fd7 100644 --- a/themes/gatsby-theme-emma/gatsby-node.js +++ b/themes/gatsby-theme-emma-core/gatsby-node.js @@ -1,241 +1,266 @@ -const fs = require(`fs`) -const kebabCase = require(`lodash.kebabcase`) -const mkdirp = require(`mkdirp`) -const path = require(`path`) - -const standardProjectsPath = `content/projects` -const standardPagesPath = `content/pages` -const standardBasePath = `/` - -exports.onPreBootstrap = ({ reporter, store }, themeOptions) => { - const { program } = store.getState() - - const projectsPath = themeOptions.projectsPath || standardProjectsPath - const pagesPath = themeOptions.pagesPath || standardPagesPath - - const dirs = [path.join(program.directory, projectsPath), path.join(program.directory, pagesPath)] - - dirs.forEach(dir => { - if (!fs.existsSync(dir)) { - reporter.info(`Creating the "${dir}" directory`) - mkdirp.sync(dir) - } - }) -} - -const mdxResolverPassthrough = fieldName => async (source, args, context, info) => { - const type = info.schema.getType(`Mdx`) - const mdxNode = context.nodeModel.getNodeById({ - id: source.parent, - }) - const resolver = type.getFields()[fieldName].resolve - const result = await resolver(mdxNode, args, context, { - fieldName, - }) - return result -} - -exports.sourceNodes = ({ actions, schema }) => { - const { createTypes } = actions - - const typeDefs = [ - schema.buildObjectType({ - name: `Project`, - fields: { - slug: { type: `String` }, - title: { type: `String` }, - client: { type: `String` }, - service: { type: `String` }, - color: { type: `String` }, - date: { type: `Date`, extensions: { dateformat: {} } }, - cover: { type: `File`, extensions: { fileByRelativePath: {} } }, - excerpt: { - type: `String`, - args: { - pruneLength: { - type: `Int`, - defaultValue: 160, - }, - }, - resolve: mdxResolverPassthrough(`excerpt`), - }, - body: { - type: `String`, - resolve: mdxResolverPassthrough(`body`), - }, - }, - interfaces: [`Node`], - extensions: { - infer: false, - }, - }), - schema.buildObjectType({ - name: `Page`, - fields: { - slug: { type: `String` }, - title: { type: `String` }, - cover: { type: `File`, extensions: { fileByRelativePath: {} } }, - excerpt: { - type: `String`, - args: { - pruneLength: { - type: `Int`, - defaultValue: 160, - }, - }, - resolve: mdxResolverPassthrough(`excerpt`), - }, - body: { - type: `String`, - resolve: mdxResolverPassthrough(`body`), - }, - }, - interfaces: [`Node`], - extensions: { - infer: false, - }, - }), - ] - - createTypes(typeDefs) -} - -exports.createResolvers = ({ createResolvers }, themeOptions) => { - const basePath = themeOptions.basePath || standardBasePath - - const slugify = str => { - const slug = kebabCase(str) - - return `/${basePath}/${slug}`.replace(/\/\/+/g, `/`) - } - - createResolvers({ - Project: { - slug: { - resolve: source => slugify(source.title), - }, - }, - }) -} - -exports.onCreateNode = ({ node, actions, getNode, createNodeId, createContentDigest }, themeOptions) => { - const { createNode, createParentChildLink } = actions - - const projectsPath = themeOptions.projectsPath || standardProjectsPath - const pagesPath = themeOptions.pagesPath || standardPagesPath - - if (node.internal.type !== `Mdx`) { - return - } - - const fileNode = getNode(node.parent) - const source = fileNode.sourceInstanceName - - // Check for "projects" and create the "Project" type - if (node.internal.type === `Mdx` && source === projectsPath) { - const fieldData = { - title: node.frontmatter.title, - client: node.frontmatter.client, - cover: node.frontmatter.cover, - date: node.frontmatter.date, - service: node.frontmatter.service, - color: node.frontmatter.color, - } - - createNode({ - ...fieldData, - id: createNodeId(`${node.id} >>> Project`), - parent: node.id, - children: [], - internal: { - type: `Project`, - contentDigest: createContentDigest(fieldData), - content: JSON.stringify(fieldData), - description: `Projects`, - }, - }) - - createParentChildLink({ parent: fileNode, child: node }) - } - - // Check for "pages" and create the "Page" type - if (node.internal.type === `Mdx` && source === pagesPath) { - const fieldData = { - title: node.frontmatter.title, - slug: node.frontmatter.slug, - cover: node.frontmatter.cover, - } - - createNode({ - ...fieldData, - id: createNodeId(`${node.id} >>> Page`), - parent: node.id, - children: [], - internal: { - type: `Page`, - contentDigest: createContentDigest(fieldData), - content: JSON.stringify(fieldData), - description: `Pages`, - }, - }) - - createParentChildLink({ parent: fileNode, child: node }) - } -} - -exports.createPages = async ({ actions, graphql, reporter }, themeOptions) => { - const { createPage } = actions - - const basePath = themeOptions.basePath || standardBasePath - - createPage({ - path: basePath, - component: require.resolve(`./src/templates/projects.tsx`), - }) - - const result = await graphql(` - query { - allProject(sort: { fields: date, order: DESC }) { - nodes { - slug - } - } - allPage { - nodes { - slug - } - } - } - `) - - if (result.errors) { - reporter.panic(`There was an error loading your projects or pages`, result.errors) - return - } - - const projects = result.data.allProject.nodes - - projects.forEach(project => { - createPage({ - path: project.slug, - component: require.resolve(`./src/templates/project.tsx`), - context: { - slug: project.slug, - }, - }) - }) - - const pages = result.data.allPage.nodes - - if (pages.length > 0) { - pages.forEach(page => { - createPage({ - path: page.slug, - component: require.resolve(`./src/templates/page.tsx`), - context: { - slug: page.slug, - }, - }) - }) - } -} +const fs = require(`fs`) +const kebabCase = require(`lodash.kebabcase`) +const mkdirp = require(`mkdirp`) +const path = require(`path`) +const withDefaults = require(`./utils/default-options`) + +// Ensure that content directories exist at site-level +// If non-existent they'll be created here (as empty folders) +exports.onPreBootstrap = ({ reporter, store }, themeOptions) => { + const { program } = store.getState() + + const { projectsPath, pagesPath } = withDefaults(themeOptions) + + const dirs = [path.join(program.directory, projectsPath), path.join(program.directory, pagesPath)] + + dirs.forEach(dir => { + if (!fs.existsSync(dir)) { + reporter.info(`Initializing "${dir}" directory`) + mkdirp.sync(dir) + } + }) +} + +const mdxResolverPassthrough = fieldName => async (source, args, context, info) => { + const type = info.schema.getType(`Mdx`) + const mdxNode = context.nodeModel.getNodeById({ + id: source.parent, + }) + const resolver = type.getFields()[fieldName].resolve + const result = await resolver(mdxNode, args, context, { + fieldName, + }) + return result +} + +// Create general interfaces that you could can use to leverage other data sources +// The core theme sets up MDX as a type for the general interface +exports.createSchemaCustomization = ({ actions, schema }, themeOptions) => { + const { createTypes } = actions + + const { basePath } = withDefaults(themeOptions) + + createTypes(` + interface Project @nodeInterface { + id: ID! + slug: String! + title: String! + client: String! + service: String! + color: String! + date: Date! @dateformat + cover: File! @fileByRelativePath + excerpt: String! + body: String! + } + + interface Page @nodeInterface { + id: ID! + slug: String! + title: String! + cover: File! @fileByRelativePath + excerpt: String! + body: String! + } + `) + + const slugify = source => { + const slug = kebabCase(source.title) + + return `/${basePath}/${slug}`.replace(/\/\/+/g, `/`) + } + + const typeDefs = [ + schema.buildObjectType({ + name: `MdxProject`, + fields: { + id: { type: `ID!` }, + title: { type: `String!` }, + slug: { type: `String!`, resolve: slugify }, + client: { type: `String!` }, + service: { type: `String!` }, + color: { type: `String!` }, + date: { type: `Date!`, extensions: { dateformat: {} } }, + cover: { type: `File!`, extensions: { fileByRelativePath: {} } }, + excerpt: { + type: `String!`, + args: { + pruneLength: { + type: `Int`, + defaultValue: 160, + }, + }, + resolve: mdxResolverPassthrough(`excerpt`), + }, + body: { + type: `String!`, + resolve: mdxResolverPassthrough(`body`), + }, + }, + interfaces: [`Node`, `Project`], + }), + schema.buildObjectType({ + name: `MdxPage`, + fields: { + id: { type: `ID!` }, + slug: { type: `String!` }, + title: { type: `String!` }, + cover: { type: `File!`, extensions: { fileByRelativePath: {} } }, + excerpt: { + type: `String!`, + args: { + pruneLength: { + type: `Int`, + defaultValue: 160, + }, + }, + resolve: mdxResolverPassthrough(`excerpt`), + }, + body: { + type: `String!`, + resolve: mdxResolverPassthrough(`body`), + }, + }, + interfaces: [`Node`, `Page`], + }), + ] + + createTypes(typeDefs) +} + +exports.onCreateNode = ({ node, actions, getNode, createNodeId, createContentDigest }, themeOptions) => { + const { createNode, createParentChildLink } = actions + + const { projectsPath, pagesPath } = withDefaults(themeOptions) + + // Make sure that it's an MDX node + if (node.internal.type !== `Mdx`) { + return + } + + // Create a source field + // And grab the sourceInstanceName to differentiate the different sources + // In this case "projectsPath" and "pagesPath" + const fileNode = getNode(node.parent) + const source = fileNode.sourceInstanceName + + // Check for "projects" and create the "Project" type + if (node.internal.type === `Mdx` && source === projectsPath) { + const fieldData = { + title: node.frontmatter.title, + client: node.frontmatter.client, + cover: node.frontmatter.cover, + date: node.frontmatter.date, + service: node.frontmatter.service, + color: node.frontmatter.color, + } + + const mdxProjectId = createNodeId(`${node.id} >>> MdxProject`) + + createNode({ + ...fieldData, + // Required fields + id: mdxProjectId, + parent: node.id, + children: [], + internal: { + type: `MdxProject`, + contentDigest: createContentDigest(fieldData), + content: JSON.stringify(fieldData), + description: `Mdx implementation of the Project interface`, + }, + }) + + createParentChildLink({ parent: node, child: getNode(mdxProjectId) }) + } + + // Check for "pages" and create the "Page" type + if (node.internal.type === `Mdx` && source === pagesPath) { + const fieldData = { + title: node.frontmatter.title, + slug: node.frontmatter.slug, + cover: node.frontmatter.cover, + } + + const mdxPageId = createNodeId(`${node.id} >>> MdxPage`) + + createNode({ + ...fieldData, + // Required fields + id: mdxPageId, + parent: node.id, + children: [], + internal: { + type: `MdxPage`, + contentDigest: createContentDigest(fieldData), + content: JSON.stringify(fieldData), + description: `Mdx implementation of the Page interface`, + }, + }) + + createParentChildLink({ parent: node, child: getNode(mdxPageId) }) + } +} + +// These template are only data-fetching wrappers that import components +const projectsTemplate = require.resolve(`./src/templates/projects-query.tsx`) +const projectTemplate = require.resolve(`./src/templates/project-query.tsx`) +const pageTemplate = require.resolve(`./src/templates/page-query.tsx`) + +exports.createPages = async ({ actions, graphql, reporter }, themeOptions) => { + const { createPage } = actions + + const { basePath } = withDefaults(themeOptions) + + createPage({ + path: basePath, + component: projectsTemplate, + }) + + const result = await graphql(` + query { + allProject(sort: { fields: date, order: DESC }) { + nodes { + id + slug + } + } + allPage { + nodes { + slug + } + } + } + `) + + if (result.errors) { + reporter.panic(`There was an error loading your projects or pages`, result.errors) + return + } + + const projects = result.data.allProject.nodes + + projects.forEach(project => { + createPage({ + path: project.slug, + component: projectTemplate, + context: { + id: project.id, + }, + }) + }) + + const pages = result.data.allPage.nodes + + if (pages.length > 0) { + pages.forEach(page => { + createPage({ + path: page.slug, + component: pageTemplate, + context: { + slug: page.slug, + }, + }) + }) + } +} diff --git a/themes/gatsby-theme-emma-core/index.js b/themes/gatsby-theme-emma-core/index.js new file mode 100644 index 000000000..172f1ae6a --- /dev/null +++ b/themes/gatsby-theme-emma-core/index.js @@ -0,0 +1 @@ +// noop diff --git a/themes/gatsby-theme-emma-core/package.json b/themes/gatsby-theme-emma-core/package.json new file mode 100644 index 000000000..baaeded1f --- /dev/null +++ b/themes/gatsby-theme-emma-core/package.json @@ -0,0 +1,49 @@ +{ + "name": "@lekoarts/gatsby-theme-emma-core", + "version": "0.0.1", + "author": "LekoArts ", + "description": "Core Theme for @lekoarts/gatsby-theme-emma. This theme implements the Project and Page node interfaces and exports templates (+ queries) which you can shadow.", + "license": "MIT", + "main": "index.js", + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "gatsby build", + "develop": "gatsby develop", + "start": "gatsby develop", + "clean": "gatsby clean" + }, + "peerDependencies": { + "@mdx-js/react": "^1.3.1", + "gatsby": "^2.13.3", + "react": "^16.9.0", + "react-dom": "^16.9.0" + }, + "dependencies": { + "@mdx-js/mdx": "^1.3.1", + "@mdx-js/react": "^1.3.1", + "gatsby-plugin-mdx": "^1.0.25", + "gatsby-plugin-sharp": "^2.2.13", + "gatsby-remark-images": "^3.1.13", + "gatsby-source-filesystem": "^2.1.10", + "gatsby-transformer-sharp": "^2.2.7", + "gatsby-plugin-typescript": "^2.1.3", + "lodash.kebabcase": "^4.1.1" + }, + "keywords": [ + "gatsby", + "gatsby-theme", + "gatsby-plugin", + "lekoarts" + ], + "bugs": { + "url": "https://github.com/LekoArts/gatsby-themes/issues" + }, + "homepage": "https://themes.lekoarts.de", + "repository": { + "type": "git", + "url": "https://github.com/LekoArts/gatsby-themes.git", + "directory": "themes/gatsby-theme-emma-core" + } +} diff --git a/themes/gatsby-theme-emma-core/src/components/page.tsx b/themes/gatsby-theme-emma-core/src/components/page.tsx new file mode 100644 index 000000000..bbfa028b2 --- /dev/null +++ b/themes/gatsby-theme-emma-core/src/components/page.tsx @@ -0,0 +1,3 @@ +import React from "react" + +export default ({ data }: { data: any }) =>
{JSON.stringify(data, null, 2)}
diff --git a/themes/gatsby-theme-emma-core/src/components/project.tsx b/themes/gatsby-theme-emma-core/src/components/project.tsx new file mode 100644 index 000000000..bbfa028b2 --- /dev/null +++ b/themes/gatsby-theme-emma-core/src/components/project.tsx @@ -0,0 +1,3 @@ +import React from "react" + +export default ({ data }: { data: any }) =>
{JSON.stringify(data, null, 2)}
diff --git a/themes/gatsby-theme-emma-core/src/components/projects.tsx b/themes/gatsby-theme-emma-core/src/components/projects.tsx new file mode 100644 index 000000000..bbfa028b2 --- /dev/null +++ b/themes/gatsby-theme-emma-core/src/components/projects.tsx @@ -0,0 +1,3 @@ +import React from "react" + +export default ({ data }: { data: any }) =>
{JSON.stringify(data, null, 2)}
diff --git a/themes/gatsby-theme-emma-core/src/templates/page-query.tsx b/themes/gatsby-theme-emma-core/src/templates/page-query.tsx new file mode 100644 index 000000000..8d27f5c45 --- /dev/null +++ b/themes/gatsby-theme-emma-core/src/templates/page-query.tsx @@ -0,0 +1,22 @@ +import { graphql } from "gatsby" +import PageComponent from "../components/page" + +export default PageComponent + +export const query = graphql` + query($slug: String!) { + page(slug: { eq: $slug }) { + title + slug + excerpt + body + cover { + childImageSharp { + fluid(maxWidth: 1920, quality: 90) { + ...GatsbyImageSharpFluid_withWebp + } + } + } + } + } +` diff --git a/themes/gatsby-theme-emma-core/src/templates/project-query.tsx b/themes/gatsby-theme-emma-core/src/templates/project-query.tsx new file mode 100644 index 000000000..73bf20396 --- /dev/null +++ b/themes/gatsby-theme-emma-core/src/templates/project-query.tsx @@ -0,0 +1,29 @@ +import { graphql } from "gatsby" +import ProjectComponent from "../components/project" + +export default ProjectComponent + +export const query = graphql` + query($id: String!) { + project(id: { eq: $id }) { + body + excerpt + client + color + date(formatString: "DD.MM.YYYY") + service + slug + title + cover { + childImageSharp { + fluid(maxWidth: 1920, quality: 90) { + ...GatsbyImageSharpFluid_withWebp + } + resize(width: 800) { + src + } + } + } + } + } +` diff --git a/themes/gatsby-theme-emma-core/src/templates/projects-query.tsx b/themes/gatsby-theme-emma-core/src/templates/projects-query.tsx new file mode 100644 index 000000000..1523d87cc --- /dev/null +++ b/themes/gatsby-theme-emma-core/src/templates/projects-query.tsx @@ -0,0 +1,25 @@ +import { graphql } from "gatsby" +import ProjectsComponent from "../components/projects" + +export default ProjectsComponent + +export const query = graphql` + query { + allProject(sort: { fields: date, order: DESC }) { + nodes { + color + slug + service + client + title + cover { + childImageSharp { + fluid(maxWidth: 850, quality: 90, traceSVG: { color: "#e6e6e6" }) { + ...GatsbyImageSharpFluid_withWebp_tracedSVG + } + } + } + } + } + } +` diff --git a/themes/gatsby-theme-emma-core/utils/default-options.js b/themes/gatsby-theme-emma-core/utils/default-options.js new file mode 100644 index 000000000..c0c50b566 --- /dev/null +++ b/themes/gatsby-theme-emma-core/utils/default-options.js @@ -0,0 +1,11 @@ +module.exports = themeOptions => { + const basePath = themeOptions.basePath || `/` + const projectsPath = themeOptions.projectsPath || `content/projects` + const pagesPath = themeOptions.pagesPath || `content/pages` + + return { + basePath, + projectsPath, + pagesPath, + } +} diff --git a/themes/gatsby-theme-emma/gatsby-config.js b/themes/gatsby-theme-emma/gatsby-config.js index 3e2f260f6..00e8a1015 100644 --- a/themes/gatsby-theme-emma/gatsby-config.js +++ b/themes/gatsby-theme-emma/gatsby-config.js @@ -1,60 +1,10 @@ -module.exports = ({ projectsPath = `content/projects`, pagesPath = `content/pages`, basePath = `/`, mdx = true }) => ({ - siteMetadata: { - siteTitle: `Emma`, - siteTitleAlt: `Emma - @lekoarts/gatsby-theme-emma`, - siteHeadline: `Emma - Gatsby Theme from @lekoarts`, - siteUrl: `https://emma.lekoarts.de`, - siteDescription: `Minimalistic portfolio with full-width grid, page transitions, support for additional MDX pages, and a focus on large images`, - siteLanguage: `en`, - siteImage: `/banner.jpg`, - author: `@lekoarts_de`, - basePath, - projectsPath, - pagesPath, - }, +module.exports = options => ({ plugins: [ { - resolve: `gatsby-source-filesystem`, - options: { - name: projectsPath, - path: projectsPath, - }, - }, - { - resolve: `gatsby-source-filesystem`, - options: { - name: pagesPath, - path: pagesPath, - }, - }, - mdx && { - resolve: `gatsby-plugin-mdx`, - options: { - gatsbyRemarkPlugins: [ - { - resolve: `gatsby-remark-images`, - options: { - maxWidth: 820, - quality: 90, - linkImagesToOriginal: false, - }, - }, - ], - plugins: [ - { - resolve: `gatsby-remark-images`, - options: { - maxWidth: 820, - quality: 90, - linkImagesToOriginal: false, - }, - }, - ], - }, + resolve: `@lekoarts/gatsby-theme-emma-core`, + options, }, `gatsby-plugin-react-helmet`, - `gatsby-plugin-sharp`, - `gatsby-transformer-sharp`, `gatsby-plugin-typescript`, `gatsby-plugin-catch-links`, `gatsby-plugin-emotion`, diff --git a/themes/gatsby-theme-emma/package.json b/themes/gatsby-theme-emma/package.json index 8b1cc4c28..4552693f5 100644 --- a/themes/gatsby-theme-emma/package.json +++ b/themes/gatsby-theme-emma/package.json @@ -21,21 +21,16 @@ }, "dependencies": { "@emotion/core": "^10.0.16", + "@lekoarts/gatsby-theme-emma-core": "^0.0.1", "@mdx-js/mdx": "^1.3.1", "@mdx-js/react": "^1.3.1", "@theme-ui/presets": "^0.2.34", "gatsby-image": "^2.2.10", "gatsby-plugin-catch-links": "^2.1.4", "gatsby-plugin-emotion": "^4.1.3", - "gatsby-plugin-mdx": "^1.0.25", "gatsby-plugin-react-helmet": "^3.1.4", - "gatsby-plugin-sharp": "^2.2.13", "gatsby-plugin-theme-ui": "^0.2.34", "gatsby-plugin-typescript": "^2.1.3", - "gatsby-remark-images": "^3.1.13", - "gatsby-source-filesystem": "^2.1.10", - "gatsby-transformer-sharp": "^2.2.7", - "lodash.kebabcase": "^4.1.1", "polished": "^3.4.1", "react-helmet": "^5.2.1", "react-spring": "^8.0.27", diff --git a/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/page.tsx b/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/page.tsx new file mode 100644 index 000000000..08dc2c6a9 --- /dev/null +++ b/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/page.tsx @@ -0,0 +1,15 @@ +import React from "react" +import Page from "../../../components/page" + +type Props = { + data: { + project: any + [key: string]: any + } +} + +export default ({ data }: Props) => { + const { page } = data + + return +} diff --git a/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/project.tsx b/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/project.tsx new file mode 100644 index 000000000..15688b70a --- /dev/null +++ b/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/project.tsx @@ -0,0 +1,15 @@ +import React from "react" +import Project from "../../../components/project" + +type Props = { + data: { + project: any + [key: string]: any + } +} + +export default ({ data }: Props) => { + const { project } = data + + return +} diff --git a/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/projects.tsx b/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/projects.tsx new file mode 100644 index 000000000..7063d3c1b --- /dev/null +++ b/themes/gatsby-theme-emma/src/@lekoarts/gatsby-theme-emma-core/components/projects.tsx @@ -0,0 +1,15 @@ +import React from "react" +import Projects from "../../../components/projects" + +type Props = { + data: { + allProject: any + [key: string]: string + } +} + +export default ({ data }: Props) => { + const { allProject } = data + + return +} diff --git a/themes/gatsby-theme-emma/src/templates/page.tsx b/themes/gatsby-theme-emma/src/components/page.tsx similarity index 70% rename from themes/gatsby-theme-emma/src/templates/page.tsx rename to themes/gatsby-theme-emma/src/components/page.tsx index 99a11fc74..333980450 100644 --- a/themes/gatsby-theme-emma/src/templates/page.tsx +++ b/themes/gatsby-theme-emma/src/components/page.tsx @@ -1,12 +1,11 @@ /** @jsx jsx */ -import { graphql } from "gatsby" import { animated, useSpring, config } from "react-spring" import { Container, Styled, jsx, Flex } from "theme-ui" import { MDXRenderer } from "gatsby-plugin-mdx" -import Layout from "../components/layout" -import SEO from "../components/seo" +import Layout from "./layout" +import SEO from "./seo" import { ChildImageSharp } from "../types" -import Hero from "../components/hero" +import Hero from "./hero" type Props = { data: { @@ -20,7 +19,7 @@ type Props = { } } -const PageTemplate = ({ data: { page } }: Props) => { +const Page = ({ data: { page } }: Props) => { const titleProps = useSpring({ config: config.slow, from: { opacity: 0, transform: `translate3d(0, -30px, 0)` }, @@ -59,22 +58,4 @@ const PageTemplate = ({ data: { page } }: Props) => { ) } -export default PageTemplate - -export const query = graphql` - query($slug: String!) { - page(slug: { eq: $slug }) { - title - slug - excerpt - body - cover { - childImageSharp { - fluid(maxWidth: 1920, quality: 90) { - ...GatsbyImageSharpFluid_withWebp - } - } - } - } - } -` +export default Page diff --git a/themes/gatsby-theme-emma/src/templates/project.tsx b/themes/gatsby-theme-emma/src/components/project.tsx similarity index 80% rename from themes/gatsby-theme-emma/src/templates/project.tsx rename to themes/gatsby-theme-emma/src/components/project.tsx index 8e99d127c..968515a3e 100644 --- a/themes/gatsby-theme-emma/src/templates/project.tsx +++ b/themes/gatsby-theme-emma/src/components/project.tsx @@ -1,138 +1,112 @@ -/** @jsx jsx */ -import { graphql } from "gatsby" -import { animated, useSpring, config } from "react-spring" -import { Container, Styled, jsx, Flex } from "theme-ui" -import { MDXRenderer } from "gatsby-plugin-mdx" -import Layout from "../components/layout" -import SEO from "../components/seo" -import { ChildImageSharp } from "../types" -import Hero from "../components/hero" - -type Props = { - data: { - project: { - body: string - excerpt: string - client: string - color: string - date: string - service: string - slug: string - title: string - cover: ChildImageSharp - } - } -} - -type ItemProps = { - name: string - content: string -} - -const Item = ({ name, content }: ItemProps) => ( - -
- {name} -
-
{content}
-
-) - -const ProjectTemplate = ({ data: { project } }: Props) => { - const titleProps = useSpring({ - config: config.slow, - from: { opacity: 0, transform: `translate3d(0, -30px, 0)` }, - to: { opacity: 1, transform: `translate3d(0, 0, 0)` }, - }) - const infoProps = useSpring({ config: config.slow, delay: 500, from: { opacity: 0 }, to: { opacity: 1 } }) - const contentProps = useSpring({ config: config.slow, delay: 1000, from: { opacity: 0 }, to: { opacity: 1 } }) - - return ( - - - - - - - - - - - {project.title} - - - - - - - - - - - - - {project.body} - - - - ) -} - -export default ProjectTemplate - -export const query = graphql` - query($slug: String!) { - project(slug: { eq: $slug }) { - body - excerpt - client - color - date(formatString: "DD.MM.YYYY") - service - slug - title - cover { - childImageSharp { - fluid(maxWidth: 1920, quality: 90) { - ...GatsbyImageSharpFluid_withWebp - } - resize(width: 800) { - src - } - } - } - } - } -` +/** @jsx jsx */ +import { animated, useSpring, config } from "react-spring" +import { Container, Styled, jsx, Flex } from "theme-ui" +import { MDXRenderer } from "gatsby-plugin-mdx" +import Layout from "./layout" +import SEO from "./seo" +import { ChildImageSharp } from "../types" +import Hero from "./hero" + +type Props = { + data: { + project: { + body: string + excerpt: string + client: string + color: string + date: string + service: string + slug: string + title: string + cover: ChildImageSharp + } + } +} + +type ItemProps = { + name: string + content: string +} + +const Item = ({ name, content }: ItemProps) => ( + +
+ {name} +
+
{content}
+
+) + +const Project = ({ data: { project } }: Props) => { + const titleProps = useSpring({ + config: config.slow, + from: { opacity: 0, transform: `translate3d(0, -30px, 0)` }, + to: { opacity: 1, transform: `translate3d(0, 0, 0)` }, + }) + const infoProps = useSpring({ config: config.slow, delay: 500, from: { opacity: 0 }, to: { opacity: 1 } }) + const contentProps = useSpring({ config: config.slow, delay: 1000, from: { opacity: 0 }, to: { opacity: 1 } }) + + return ( + + + + + + + + + + + {project.title} + + + + + + + + + + + + + {project.body} + + + + ) +} + +export default Project diff --git a/themes/gatsby-theme-emma/src/templates/projects.tsx b/themes/gatsby-theme-emma/src/components/projects.tsx similarity index 64% rename from themes/gatsby-theme-emma/src/templates/projects.tsx rename to themes/gatsby-theme-emma/src/components/projects.tsx index 2473c817f..051c21220 100644 --- a/themes/gatsby-theme-emma/src/templates/projects.tsx +++ b/themes/gatsby-theme-emma/src/components/projects.tsx @@ -1,104 +1,74 @@ -/** @jsx jsx */ -import { jsx, Container, Styled } from "theme-ui" -import { useTrail } from "react-spring" -import { graphql } from "gatsby" -import Layout from "../components/layout" -import { ChildImageSharp } from "../types" -import ProjectItem from "../components/project-item" - -type Props = { - data: { - allProject: { - nodes: { - color: string - slug: string - title: string - service: string - client: string - cover: ChildImageSharp - }[] - } - } -} - -const Projects = ({ - data: { - allProject: { nodes }, - }, -}: Props) => { - const trail = useTrail(nodes.length, { - from: { height: `0%` }, - to: { height: `100%` }, - }) - - if (nodes.length === 0) { - return ( - - - - Hi!{` `} - - 👋 - - {` `} -
- Thanks for using @lekoarts/gatsby-theme-emma. You currently don't have any content in your{` `} - projects folder - that's why this page displays a placeholder text. Head over to the{` `} - - README - - {` `} - to learn how to setup them. -
- - TL;DR:
- The starter automatically created the folder content/projects. Go into this folder, create a - new folder called example and create an index.mdx file there and place an image. - Edit the frontmatter like described in the{` `} - - README - - . -
-
-
- ) - } - - return ( - - {trail.map((style, index) => ( - - ))} - - ) -} - -export default Projects - -export const pageQuery = graphql` - query { - allProject(sort: { fields: date, order: DESC }) { - nodes { - color - slug - service - client - title - cover { - childImageSharp { - fluid(maxWidth: 850, quality: 90, traceSVG: { color: "#e6e6e6" }) { - ...GatsbyImageSharpFluid_withWebp_tracedSVG - } - } - } - } - } - } -` +/** @jsx jsx */ +import { jsx, Container, Styled } from "theme-ui" +import { useTrail } from "react-spring" +import Layout from "./layout" +import { ChildImageSharp } from "../types" +import ProjectItem from "./project-item" + +type Props = { + projects: { + color: string + slug: string + title: string + service: string + client: string + cover: ChildImageSharp + }[] +} + +const Projects = ({ projects }: Props) => { + const trail = useTrail(projects.length, { + from: { height: `0%` }, + to: { height: `100%` }, + }) + + if (projects.length === 0) { + return ( + + + + Hi!{` `} + + 👋 + + {` `} +
+ Thanks for using @lekoarts/gatsby-theme-emma. You currently don't have any content in your{` `} + projects folder - that's why this page displays a placeholder text. Head over to the{` `} + + README + + {` `} + to learn how to setup them. +
+ + TL;DR:
+ The starter automatically created the folder content/projects. Go into this folder, create a + new folder called example and create an index.mdx file there and place an image. + Edit the frontmatter like described in the{` `} + + README + + . +
+
+
+ ) + } + + return ( + + {trail.map((style, index) => ( + + ))} + + ) +} + +export default Projects diff --git a/themes/gatsby-theme-emma/src/index.d.ts b/themes/gatsby-theme-emma/src/index.d.ts index d6859713e..de2cfe397 100644 --- a/themes/gatsby-theme-emma/src/index.d.ts +++ b/themes/gatsby-theme-emma/src/index.d.ts @@ -1,21 +1,5 @@ -declare module 'gatsby-plugin-mdx' - declare namespace React { interface MetaHTMLAttributes { value?: string } } - -declare module '*.mdx' { - let MDXComponent: (props) => JSX.Element; - export default MDXComponent; -} - -declare module "@mdx-js/react" { - import { ComponentType, StyleHTMLAttributes } from "react" - type MDXProps = { - children: React.ReactNode - components: { wrapper: React.ReactNode } - } - export class MDXProvider extends React.Component {} -} \ No newline at end of file