Skip to content

Commit

Permalink
Garden: Smooth Shadows for Images (LekoArts#23)
Browse files Browse the repository at this point in the history
* proper mdx format

* customize alert mdx component

* add post

* prettier change
  • Loading branch information
LekoArts authored Jul 28, 2021
1 parent 38e6d79 commit c6a7993
Show file tree
Hide file tree
Showing 27 changed files with 515 additions and 268 deletions.
6 changes: 6 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
trailingComma: `es5`,
semi: false,
singleQuote: false,
printWidth: 80, // To make code blocks on the website more readable
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module.exports = {
options: {},
},
],
};
}
```

You can also use the preview page as a starter project, by using the Gatsby CLI (you need to install that first if you haven't done so already):
Expand Down Expand Up @@ -62,7 +62,7 @@ import {
Space,
Table,
Video,
} from "@lekoarts/gatsby-theme-specimens";
} from "@lekoarts/gatsby-theme-specimens"
```

The [interactive preview](https://specimens.lekoarts.de/) shows you how to use these components.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ tags:
Integrating syntax highlighting in Gatsby is solvable with solutions like [`gatsby-remark-prismjs`](https://www.gatsbyjs.com/plugins/gatsby-remark-prismjs/) or [`prism-react-renderer`](https://github.com/FormidableLabs/prism-react-renderer). When creating the code block in Markdown you specify the desired language (e.g. js or css) after the opening three backticks. It's a nice touch to display the specified language also in the code block itself, like I do it on my blog here:

```js
const harry = spell("lumos");
const harry = spell("lumos")
```

The following two quick tips explain how to integrate this feature with `gatsby-remark-prismjs` or `prism-react-renderer` (Markdown or MDX respectively).
Expand All @@ -24,7 +24,7 @@ Set up a Gatsby project which allows you to source data from Markdown. You can e

````md
```js
const harry = spell("lumos");
const harry = spell("lumos")
```
````

Expand Down Expand Up @@ -84,8 +84,8 @@ To get the CSS from `custom-prism-styles.css` to work, you'll need to think of a
The main part is to create a `<Code />` component and mapping it to the `pre` tag in MDX. The [language-tabs-mdx](https://codesandbox.io/s/language-tabs-mdx-g03g6) codesandbox shows the complete setup, here's the code component as a snippet:

```js title=src/components/code.js
import React from "react";
import Highlight, { defaultProps } from "prism-react-renderer";
import React from "react"
import Highlight, { defaultProps } from "prism-react-renderer"

const Code = () => (
<Highlight {...defaultProps} code={codeString} language={language}>
Expand All @@ -103,9 +103,9 @@ const Code = () => (
</div>
)}
</Highlight>
);
)

export default Code;
export default Code
```

If you now start the development server and inspect the HTML the extra container will be in the DOM. Should work with the above CSS now, right? Not quite yet, one small adjustment needs to be made. As you can see in the DOM, the pre element now has two classes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ Add this to the existing `gatsby-node.js` file:

```js title=gatsby-node.js
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes, createFieldExtension } = actions;
const { createTypes, createFieldExtension } = actions

createFieldExtension({
name: "defaultFalse",
extend() {
return {
resolve(source, args, context, info) {
if (source[info.fieldName] == null) {
return false;
return false
}
return source[info.fieldName];
return source[info.fieldName]
},
};
}
},
});
})

createTypes(`
type MarkdownRemark implements Node {
Expand All @@ -45,8 +45,8 @@ exports.createSchemaCustomization = ({ actions }) => {
type Frontmatter {
draft: Boolean @defaultFalse
}
`);
};
`)
}
```

In the `createTypes` function you have to define a nested type on the `MarkdownRemark` type (read [Nested types](https://www.gatsbyjs.com/docs/reference/graphql-data-layer/schema-customization/#nested-types) for more info) to be able to type the draft field. On the draft field itself the custom extension is used as a directive. The directive allows you to reuse this action on other fields, too. In case you're using a CMS or other datasource than markdown you'll need to find and define your type (instead of `MarkdownRemark`) to have this working. I'd recommend using GraphiQL (`localhost:8000/___graphql`) if you're unsure about the names!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Add to your `gatsby-node.js` file:

```js title=gatsby-node.js {9}
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
const { createTypes } = actions
const typeDefs = `
type MarkdownRemark implements Node {
frontmatter: Frontmatter
Expand All @@ -80,9 +80,9 @@ exports.createSchemaCustomization = ({ actions }) => {
type Frontmatter {
authors: [AuthorsYaml] @link(by: "name")
}
`;
createTypes(typeDefs);
};
`
createTypes(typeDefs)
}
```

In order to explicitly define the nested frontmatter you first need define root type `MarkdownRemark` that then has the custom type `Frontmatter`. The part `implements Node` means that the type will use the `Node` interface that defines set of fields common to node objects created by source plugins/transformers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ npm install lodash.get
Open your `gatsby-node.js` file and add the installed package, and the boilerplate to use [Gatsby's schema customization API](https://www.gatsbyjs.com/docs/reference/graphql-data-layer/schema-customization/):

```js title=gatsby-node.js
const get = require("lodash.get");
const get = require("lodash.get")

exports.createSchemaCustomization = ({ actions }) => {
const { createTypes, createFieldExtension } = actions;
};
const { createTypes, createFieldExtension } = actions
}
```

With the function `createTypes` you'll explicitly define the GraphQL types (in this case in GraphQL [SDL](https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51) syntax), with `createFieldExtension` you'll create a so called directive/extension that you then can reuse throughout your types.
Expand All @@ -48,17 +48,17 @@ Since gatsby-starter-blog is powered by Markdown you'll want to add your `isFutu
Adding this type definition defines the mentioned field at the root of the Markdown type:

```js title=gatsby-node.js {6-10}
const get = require("lodash.get");
const get = require("lodash.get")

exports.createSchemaCustomization = ({ actions }) => {
const { createTypes, createFieldExtension } = actions;
const { createTypes, createFieldExtension } = actions

createTypes(`
type MarkdownRemark implements Node {
isFuture: Boolean!
}
`);
};
`)
}
```

The notation `Boolean!` means that the field is of type Boolean and is Non-Nullable.
Expand All @@ -68,49 +68,49 @@ The notation `Boolean!` means that the field is of type Boolean and is Non-Nulla
In the next step you'll create the helper function that returns either true or false depending on whether the input date is in the future or not.

```js title=gatsby-node.js {6-9}
const get = require("lodash.get");
const get = require("lodash.get")

exports.createSchemaCustomization = ({ actions }) => {
const { createTypes, createFieldExtension } = actions;
const { createTypes, createFieldExtension } = actions

const isFuture = (fieldName) => (source) => {
const date = get(source, fieldName);
return new Date(date) > new Date();
};
const date = get(source, fieldName)
return new Date(date) > new Date()
}

createTypes(`
type MarkdownRemark implements Node {
isFuture: Boolean!
}
`);
};
`)
}
```

The concept used there is called [Currying](https://en.wikipedia.org/wiki/Currying). For this example it means:

If you run `isFuture("myName")` you'll receive a function:

```js
(source) => {
const date = get(source, "myName");
return new Date(date) > new Date();
};
;(source) => {
const date = get(source, "myName")
return new Date(date) > new Date()
}
```

So what is that function doing? With the `lodash.get` function you're able to input a string with only one word (e.g. _myName_) or a word with dot notation (e.g. _myName.field_). The latter is used to access information in objects. The `lodash.get` function translates the string and enables you to access that information. If you later `console.log(source)` you'll see that you have access to `source.frontmatter` and other fields. It then checks the date with the current date and returns true if it's in the future, otherwise false.

Next, use `createFieldExtension` and the just created `isFuture` function:

```js title=gatsby-node.js {11-21}
const get = require("lodash.get");
const get = require("lodash.get")

exports.createSchemaCustomization = ({ actions }) => {
const { createTypes, createFieldExtension } = actions;
const { createTypes, createFieldExtension } = actions

const isFuture = (fieldName) => (source) => {
const date = get(source, fieldName);
return new Date(date) > new Date();
};
const date = get(source, fieldName)
return new Date(date) > new Date()
}

createFieldExtension({
name: "isFuture",
Expand All @@ -120,25 +120,25 @@ exports.createSchemaCustomization = ({ actions }) => {
extend({ fieldName }) {
return {
resolve: isFuture(fieldName),
};
}
},
});
})

createTypes(`
type MarkdownRemark implements Node {
isFuture: Boolean!
}
`);
};
`)
}
```

`createFieldExtension` accepts three arguments. `name` will be name of the directive, `args` the information you can give it and `extend` is a function that has to return a (partial) field config. In more verbose terms (including `isFuture`) you could write it like this:

```js
const isFuture = (fieldName, source) => {
const date = get(source, fieldName);
return new Date(date) > new Date();
};
const date = get(source, fieldName)
return new Date(date) > new Date()
}

createFieldExtension({
name: "isFuture",
Expand All @@ -148,27 +148,27 @@ createFieldExtension({
extend(options) {
return {
resolve(source) {
return isFuture(options.fieldName, source);
return isFuture(options.fieldName, source)
},
};
}
},
});
})
```

So the the code you'll be using is destructuring the `options` and passing `source` via _Currying_ to `isFuture`.

After adding the field extension to the field, the final code should look like:

```js title=gatsby-node.js {25}
const get = require("lodash.get");
const get = require("lodash.get")

exports.createSchemaCustomization = ({ actions }) => {
const { createTypes, createFieldExtension } = actions;
const { createTypes, createFieldExtension } = actions

const isFuture = (fieldName) => (source) => {
const date = get(source, fieldName);
return new Date(date) > new Date();
};
const date = get(source, fieldName)
return new Date(date) > new Date()
}

createFieldExtension({
name: "isFuture",
Expand All @@ -178,16 +178,16 @@ exports.createSchemaCustomization = ({ actions }) => {
extend({ fieldName }) {
return {
resolve: isFuture(fieldName),
};
}
},
});
})

createTypes(`
type MarkdownRemark implements Node {
isFuture: Boolean! @isFuture(fieldName: "frontmatter.date")
}
`);
};
`)
}
```

As the date is defined in the frontmatter the fieldName is `frontmatter.date`. If you would place the `isFuture` field in the frontmatter itself you would use only `date` for the `fieldName`.
Expand Down
Loading

0 comments on commit c6a7993

Please sign in to comment.