docs: convert website from postcss to emotion (#2068)
This commit is contained in:
parent
7b0838dfef
commit
3d474b1944
@ -1,46 +1,14 @@
|
|||||||
{
|
{
|
||||||
presets: [
|
"presets": ["babel-preset-gatsby"],
|
||||||
|
"plugins": [
|
||||||
[
|
[
|
||||||
"@babel/preset-env",
|
"prismjs",
|
||||||
{
|
{
|
||||||
loose: true,
|
|
||||||
modules: false,
|
|
||||||
useBuiltIns: "usage",
|
|
||||||
shippedProposals: true,
|
|
||||||
targets: {
|
|
||||||
browsers: [">0.25%", "not dead"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"@babel/preset-react",
|
|
||||||
{
|
|
||||||
useBuiltIns: true,
|
|
||||||
pragma: "React.createElement",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
["prismjs", {
|
|
||||||
"languages": ["javascript", "css", "markup", "yaml", "json"],
|
"languages": ["javascript", "css", "markup", "yaml", "json"],
|
||||||
"plugins": ["line-numbers"],
|
"plugins": ["line-numbers"],
|
||||||
"theme": "tomorrow",
|
"theme": "tomorrow",
|
||||||
"css": true,
|
"css": true
|
||||||
}],
|
}
|
||||||
[
|
]
|
||||||
"@babel/plugin-proposal-class-properties",
|
]
|
||||||
{
|
|
||||||
loose: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"@babel/plugin-syntax-dynamic-import",
|
|
||||||
"babel-plugin-macros",
|
|
||||||
[
|
|
||||||
"@babel/plugin-transform-runtime",
|
|
||||||
{
|
|
||||||
helpers: true,
|
|
||||||
regenerator: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": [
|
|
||||||
"stylelint-config-recommended"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"at-rule-no-unknown": [true, {
|
|
||||||
"ignoreAtRules": ["/^neat/"]
|
|
||||||
}],
|
|
||||||
"no-descending-specificity": null
|
|
||||||
}
|
|
||||||
}
|
|
@ -68,7 +68,6 @@ Then import it (assuming your project has tooling for imports):
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
import CMS from 'netlify-cms'
|
import CMS from 'netlify-cms'
|
||||||
|
|
||||||
// Now the registry is available via the CMS object.
|
// Now the registry is available via the CMS object.
|
||||||
CMS.registerPreviewTemplate('my-template', MyTemplate)
|
CMS.registerPreviewTemplate('my-template', MyTemplate)
|
||||||
```
|
```
|
||||||
|
@ -19,11 +19,10 @@ To use it in your own project stored on GitHub or GitLab, follow these steps:
|
|||||||
|
|
||||||
1. Head over to the [Netlify Identity docs](https://www.netlify.com/docs/identity) and follow the steps to get started.
|
1. Head over to the [Netlify Identity docs](https://www.netlify.com/docs/identity) and follow the steps to get started.
|
||||||
2. Add the following lines to your Netlify CMS `config.yml` file:
|
2. Add the following lines to your Netlify CMS `config.yml` file:
|
||||||
|
```yaml
|
||||||
```yaml
|
backend:
|
||||||
backend:
|
name: git-gateway
|
||||||
name: git-gateway
|
```
|
||||||
```
|
|
||||||
|
|
||||||
### Reconnect after Changing Repository Permissions
|
### Reconnect after Changing Repository Permissions
|
||||||
|
|
||||||
@ -45,12 +44,11 @@ To enable basic GitHub authentication:
|
|||||||
|
|
||||||
1. Follow the authentication provider setup steps in the [Netlify docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider).
|
1. Follow the authentication provider setup steps in the [Netlify docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider).
|
||||||
2. Add the following lines to your Netlify CMS `config.yml` file:
|
2. Add the following lines to your Netlify CMS `config.yml` file:
|
||||||
|
```yaml
|
||||||
```yaml
|
backend:
|
||||||
backend:
|
name: github
|
||||||
name: github
|
repo: owner-name/repo-name # Path to your GitHub repository
|
||||||
repo: owner-name/repo-name # Path to your GitHub repository
|
```
|
||||||
```
|
|
||||||
|
|
||||||
### Specifying a status for deploy previews
|
### Specifying a status for deploy previews
|
||||||
The GitHub backend supports [deploy preview links](../deploy-preview-links). Netlify CMS checks the
|
The GitHub backend supports [deploy preview links](../deploy-preview-links). Netlify CMS checks the
|
||||||
@ -58,7 +56,6 @@ The GitHub backend supports [deploy preview links](../deploy-preview-links). Net
|
|||||||
one that seems to represent a deploy preview. If you need to customize this behavior, you can
|
one that seems to represent a deploy preview. If you need to customize this behavior, you can
|
||||||
specify which context to look for using `preview_context`:
|
specify which context to look for using `preview_context`:
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
backend:
|
backend:
|
||||||
name: github
|
name: github
|
||||||
@ -87,11 +84,11 @@ To enable it:
|
|||||||
2. Follow the [Netlify docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider) to add your new GitLab Application ID and Secret to your Netlify site dashboard.
|
2. Follow the [Netlify docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider) to add your new GitLab Application ID and Secret to your Netlify site dashboard.
|
||||||
3. In your repository, add the following lines to your Netlify CMS `config.yml` file:
|
3. In your repository, add the following lines to your Netlify CMS `config.yml` file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
backend:
|
backend:
|
||||||
name: gitlab
|
name: gitlab
|
||||||
repo: owner-name/repo-name # Path to your GitLab repository
|
repo: owner-name/repo-name # Path to your GitLab repository
|
||||||
```
|
```
|
||||||
|
|
||||||
### Client-Side Implicit Grant (GitLab)
|
### Client-Side Implicit Grant (GitLab)
|
||||||
|
|
||||||
|
@ -215,20 +215,15 @@ Assuming you have the netlify-cms package installed to your project, manual init
|
|||||||
```js
|
```js
|
||||||
// This global flag enables manual initialization.
|
// This global flag enables manual initialization.
|
||||||
window.CMS_MANUAL_INIT = true
|
window.CMS_MANUAL_INIT = true
|
||||||
|
|
||||||
// Usage with import from npm package
|
// Usage with import from npm package
|
||||||
import CMS, { init } from 'netlify-cms'
|
import CMS, { init } from 'netlify-cms'
|
||||||
|
|
||||||
// Usage with script tag
|
// Usage with script tag
|
||||||
const { CMS, initCMS: init } = window
|
const { CMS, initCMS: init } = window
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize without passing in config - equivalent to just importing
|
* Initialize without passing in config - equivalent to just importing
|
||||||
* Netlify CMS the old way.
|
* Netlify CMS the old way.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
init()
|
init()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionally pass in a config object. This object will be merged into
|
* Optionally pass in a config object. This object will be merged into
|
||||||
* `config.yml` if it exists, and any portion that conflicts with
|
* `config.yml` if it exists, and any portion that conflicts with
|
||||||
@ -239,7 +234,6 @@ init()
|
|||||||
* your `config.yml` can be missing its backend property, allowing you
|
* your `config.yml` can be missing its backend property, allowing you
|
||||||
* to set this property at runtime.
|
* to set this property at runtime.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
init({
|
init({
|
||||||
config: {
|
config: {
|
||||||
backend: {
|
backend: {
|
||||||
@ -247,7 +241,6 @@ init({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionally pass in a complete config object and set a flag
|
* Optionally pass in a complete config object and set a flag
|
||||||
* (`load_config_file: false`) to ignore the `config.yml`.
|
* (`load_config_file: false`) to ignore the `config.yml`.
|
||||||
@ -257,7 +250,6 @@ init({
|
|||||||
* It is not required if the `config.yml` file is missing to set
|
* It is not required if the `config.yml` file is missing to set
|
||||||
* `load_config_file`, but will improve performance and avoid a load error.
|
* `load_config_file`, but will improve performance and avoid a load error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
init({
|
init({
|
||||||
config: {
|
config: {
|
||||||
backend: {
|
backend: {
|
||||||
@ -276,7 +268,6 @@ init({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// The registry works as expected, and can be used before or after init.
|
// The registry works as expected, and can be used before or after init.
|
||||||
CMS.registerPreviewTemplate(...);
|
CMS.registerPreviewTemplate(...);
|
||||||
```
|
```
|
||||||
@ -292,7 +283,6 @@ CMS.registerPreviewTemplate(...);
|
|||||||
*/
|
*/
|
||||||
import CMS from 'netlify-cms';
|
import CMS from 'netlify-cms';
|
||||||
import styles from '!css-loader!sass-loader!../main.scss'
|
import styles from '!css-loader!sass-loader!../main.scss'
|
||||||
|
|
||||||
CMS.registerPreviewStyle(styles.toString(), { raw: true })
|
CMS.registerPreviewStyle(styles.toString(), { raw: true })
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ You can [sign up for Cloudinary](https://cloudinary.com/users/register/free) for
|
|||||||
|
|
||||||
To use the Cloudinary media library within Netlify CMS, you'll need to update your Netlify CMS configuration file with the information from your Cloudinary account:
|
To use the Cloudinary media library within Netlify CMS, you'll need to update your Netlify CMS configuration file with the information from your Cloudinary account:
|
||||||
|
|
||||||
```yml
|
```yaml
|
||||||
media_library:
|
media_library:
|
||||||
name: cloudinary
|
name: cloudinary
|
||||||
config:
|
config:
|
||||||
@ -70,17 +70,17 @@ Global configuration, which is meant to affect the Cloudinary widget at all time
|
|||||||
as seen below, under the primary `media_library` property. Settings applied here will affect every
|
as seen below, under the primary `media_library` property. Settings applied here will affect every
|
||||||
instance of the Cloudinary widget.
|
instance of the Cloudinary widget.
|
||||||
|
|
||||||
```yml
|
```yaml
|
||||||
# global
|
# global
|
||||||
media_library:
|
media_library:
|
||||||
name: cloudinary
|
name: cloudinary
|
||||||
output_filename_only: false
|
output_filename_only: false
|
||||||
config:
|
config:
|
||||||
default_transformations:
|
default_transformations:
|
||||||
- - fetch_format: auto
|
- - fetch_format: auto
|
||||||
width: 160
|
width: 160
|
||||||
quality: auto
|
quality: auto
|
||||||
crop: scale
|
crop: scale
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Field configuration
|
#### Field configuration
|
||||||
@ -89,22 +89,22 @@ Configuration can also be provided for individual fields that use the media libr
|
|||||||
is very similar to the global configuration, except the settings are added to an individual `field`.
|
is very similar to the global configuration, except the settings are added to an individual `field`.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```yml
|
```yaml
|
||||||
# field
|
# field
|
||||||
fields: # The fields each document in this collection have
|
fields: # The fields each document in this collection have
|
||||||
- label: 'Cover Image'
|
- label: 'Cover Image'
|
||||||
name: 'image'
|
name: 'image'
|
||||||
widget: 'image'
|
widget: 'image'
|
||||||
required: false
|
required: false
|
||||||
tagname: ''
|
tagname: ''
|
||||||
media_library:
|
media_library:
|
||||||
config:
|
config:
|
||||||
default_transformations:
|
default_transformations:
|
||||||
- - fetch_format: auto
|
- fetch_format: auto
|
||||||
width: 300
|
width: 300
|
||||||
quality: auto
|
quality: auto
|
||||||
crop: fill
|
crop: fill
|
||||||
effect: grayscale
|
effect: grayscale
|
||||||
```
|
```
|
||||||
|
|
||||||
## Inserting Cloudinary URL in page templates
|
## Inserting Cloudinary URL in page templates
|
||||||
@ -113,24 +113,22 @@ If you prefer to provide direction so that images are transformed in a specific
|
|||||||
|
|
||||||
* Either globally or for specific fields, configure the Cloudinary extension to only output the asset filename
|
* Either globally or for specific fields, configure the Cloudinary extension to only output the asset filename
|
||||||
|
|
||||||
```yml
|
```yaml
|
||||||
# global
|
# global
|
||||||
media_library:
|
media_library:
|
||||||
name: cloudinary
|
name: cloudinary
|
||||||
output_filename_only: true
|
output_filename_only: true
|
||||||
|
# field
|
||||||
# field
|
media_library:
|
||||||
media_library:
|
name: cloudinary
|
||||||
name: cloudinary
|
output_filename_only: true
|
||||||
output_filename_only: true
|
```
|
||||||
```
|
|
||||||
|
|
||||||
* Provide a dynamic URL in the site template
|
* Provide a dynamic URL in the site template
|
||||||
|
|
||||||
```hbs
|
```handlebars
|
||||||
{{! handlebars example }}
|
{{! handlebars example }}
|
||||||
|
<img src="https://res.cloudinary.com/<cloud_name>/<resource_type>/<type>/<transformations>/{{image}}"/>
|
||||||
<img src="https://res.cloudinary.com/<cloud_name>/<resource_type>/<type>/<transformations>/{{image}}"/>
|
```
|
||||||
```
|
|
||||||
|
|
||||||
Your dynamic URL can be formed conditionally to provide any desired transformations - please see Cloudinary's [image transformation reference](https://cloudinary.com/documentation/image_transformation_reference) for available transformations.
|
Your dynamic URL can be formed conditionally to provide any desired transformations - please see Cloudinary's [image transformation reference](https://cloudinary.com/documentation/image_transformation_reference) for available transformations.
|
||||||
|
@ -9,7 +9,6 @@ Alternatively, you can specify a custom config file using a link tag:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- Note the "type" and "rel" attribute values, which are required. -->
|
<!-- Note the "type" and "rel" attribute values, which are required. -->
|
||||||
|
|
||||||
<link href="path/to/config.yml" type="text/yaml" rel="cms-config-url">
|
<link href="path/to/config.yml" type="text/yaml" rel="cms-config-url">
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ to a post in your repo may look like `content/blog/2018-01-new-post.md`, but the
|
|||||||
on your site would look more like: `/blog/2018-01-new-post/`. Here's how you would use
|
on your site would look more like: `/blog/2018-01-new-post/`. Here's how you would use
|
||||||
`preview_path` in your configuration for this scenario:
|
`preview_path` in your configuration for this scenario:
|
||||||
|
|
||||||
```yml
|
```yaml
|
||||||
collections:
|
collections:
|
||||||
- name: blog
|
- name: blog
|
||||||
folder: content/blog
|
folder: content/blog
|
||||||
@ -65,9 +65,8 @@ template, `{{slug}}` is only the url-safe [identifier
|
|||||||
field](../configuration-options/#identifier_field), while in the `preview_path` template, `{{slug}}`
|
field](../configuration-options/#identifier_field), while in the `preview_path` template, `{{slug}}`
|
||||||
is the entire slug for the entry. For example:
|
is the entire slug for the entry. For example:
|
||||||
|
|
||||||
```yml
|
```yaml
|
||||||
# for an entry created Jan 1, 2000 with identifier "My New Post!"
|
# for an entry created Jan 1, 2000 with identifier "My New Post!"
|
||||||
|
|
||||||
collections:
|
collections:
|
||||||
- name: posts
|
- name: posts
|
||||||
slug: {{year}}-{{month}}-{{slug}} # {{slug}} will compile to "my-new-post"
|
slug: {{year}}-{{month}}-{{slug}} # {{slug}} will compile to "my-new-post"
|
||||||
@ -91,7 +90,6 @@ through static site generators.
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# This collection's date field will be inferred because it has a field named `"date"`
|
# This collection's date field will be inferred because it has a field named `"date"`
|
||||||
|
|
||||||
collections:
|
collections:
|
||||||
- name: posts
|
- name: posts
|
||||||
preview_path: blog/{{year}}/{{month}}/{{title}}
|
preview_path: blog/{{year}}/{{month}}/{{title}}
|
||||||
@ -99,9 +97,7 @@ collections:
|
|||||||
- { name: title, label: Title }
|
- { name: title, label: Title }
|
||||||
{ name: date, label: Date, widget: date }
|
{ name: date, label: Date, widget: date }
|
||||||
{ name: body, label: Body, widget: markdown }
|
{ name: body, label: Body, widget: markdown }
|
||||||
|
|
||||||
# This collection requires `path_preview_date_field` because the no obvious date field is available
|
# This collection requires `path_preview_date_field` because the no obvious date field is available
|
||||||
|
|
||||||
collections:
|
collections:
|
||||||
- name: posts
|
- name: posts
|
||||||
preview_path: blog/{{year}}/{{month}}/{{title}}
|
preview_path: blog/{{year}}/{{month}}/{{title}}
|
||||||
|
@ -70,7 +70,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
'gatsby-transformer-yaml',
|
'gatsby-transformer-yaml',
|
||||||
'gatsby-transformer-json',
|
'gatsby-transformer-json',
|
||||||
'gatsby-plugin-postcss',
|
'gatsby-plugin-emotion',
|
||||||
'gatsby-plugin-react-helmet',
|
'gatsby-plugin-react-helmet',
|
||||||
'gatsby-plugin-catch-links',
|
'gatsby-plugin-catch-links',
|
||||||
{
|
{
|
||||||
@ -80,7 +80,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resolve: `gatsby-plugin-manifest`,
|
resolve: 'gatsby-plugin-manifest',
|
||||||
options: {
|
options: {
|
||||||
name: 'NetlifyCMS',
|
name: 'NetlifyCMS',
|
||||||
short_name: 'NetlifyCMS',
|
short_name: 'NetlifyCMS',
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { createFilePath } = require('gatsby-source-filesystem');
|
const { createFilePath } = require('gatsby-source-filesystem');
|
||||||
|
|
||||||
exports.createPages = async ({ graphql, boundActionCreators }) => {
|
exports.createPages = async ({ graphql, actions }) => {
|
||||||
const { createPage } = boundActionCreators;
|
const { createPage } = actions;
|
||||||
|
|
||||||
const docPage = path.resolve('./src/templates/doc-page.js');
|
const docPage = path.resolve('./src/templates/doc-page.js');
|
||||||
const blogPost = path.resolve('./src/templates/blog-post.js');
|
const blogPost = path.resolve('./src/templates/blog-post.js');
|
||||||
@ -51,8 +51,8 @@ exports.createPages = async ({ graphql, boundActionCreators }) => {
|
|||||||
|
|
||||||
const pad = n => (n >= 10 ? n : `0${n}`);
|
const pad = n => (n >= 10 ? n : `0${n}`);
|
||||||
|
|
||||||
exports.onCreateNode = ({ node, boundActionCreators, getNode }) => {
|
exports.onCreateNode = ({ node, actions, getNode }) => {
|
||||||
const { createNodeField } = boundActionCreators;
|
const { createNodeField } = actions;
|
||||||
|
|
||||||
if (node.internal.type === 'MarkdownRemark') {
|
if (node.internal.type === 'MarkdownRemark') {
|
||||||
const value = createFilePath({ node, getNode });
|
const value = createFilePath({ node, getNode });
|
||||||
|
@ -13,38 +13,38 @@
|
|||||||
"homepage": "https://www.netlifycms.org/",
|
"homepage": "https://www.netlifycms.org/",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"classnames": "^2.2.5",
|
"@emotion/core": "^10.0.27",
|
||||||
"dayjs": "^1.7.5",
|
"@emotion/styled": "^10.0.27",
|
||||||
"gatsby": "next",
|
"dayjs": "^1.8.19",
|
||||||
"gatsby-plugin-catch-links": "next",
|
"emotion-theming": "^10.0.27",
|
||||||
"gatsby-plugin-manifest": "next",
|
"gatsby": "2.19.3",
|
||||||
"gatsby-plugin-netlify-cms": "^3.0.0-rc.1",
|
"gatsby-plugin-catch-links": "2.1.24",
|
||||||
"gatsby-plugin-postcss": "^1.0.0",
|
"gatsby-plugin-emotion": "^4.1.21",
|
||||||
"gatsby-plugin-react-helmet": "next",
|
"gatsby-plugin-manifest": "2.2.38",
|
||||||
"gatsby-remark-autolink-headers": "next",
|
"gatsby-plugin-netlify-cms": "^4.1.37",
|
||||||
"gatsby-remark-prismjs": "next",
|
"gatsby-plugin-react-helmet": "3.1.21",
|
||||||
"gatsby-source-filesystem": "next",
|
"gatsby-remark-autolink-headers": "2.1.23",
|
||||||
"gatsby-transformer-json": "next",
|
"gatsby-remark-prismjs": "3.3.30",
|
||||||
"gatsby-transformer-remark": "next",
|
"gatsby-source-filesystem": "2.1.46",
|
||||||
"gatsby-transformer-yaml": "next",
|
"gatsby-transformer-json": "2.2.25",
|
||||||
"github-buttons": "git+https://github.com/ntkme/github-buttons.git",
|
"gatsby-transformer-remark": "2.6.48",
|
||||||
"lodash": "^4.17.13",
|
"gatsby-transformer-yaml": "2.2.23",
|
||||||
"netlify-cms": "^2.0.11",
|
"lodash": "^4.17.15",
|
||||||
"postcss-at2x": "^2.0.0",
|
"moment": "^2.24.0",
|
||||||
"postcss-cssnext": "^2.7.0",
|
"netlify-cms": "^2.10.11",
|
||||||
"postcss-neat": "^2.5.2",
|
"prismjs": "^1.19.0",
|
||||||
"postcss-nested": "^1.0.0",
|
"react": "^16.12.0",
|
||||||
"postcss-simple-extend": "^1.0.0",
|
"react-dom": "^16.12.0",
|
||||||
"postcss-simple-vars-async": "^1.2.1",
|
"react-github-btn": "^1.1.1",
|
||||||
"prismjs": "^1.15.0",
|
"react-helmet": "^5.2.1",
|
||||||
"react": "^16.4.2",
|
"react-markdown": "^4.3.1",
|
||||||
"react-dom": "^16.4.2",
|
"smooth-scroll": "^16.1.2"
|
||||||
"react-helmet": "^5.2.0",
|
|
||||||
"react-markdown": "^3.3.2",
|
|
||||||
"smooth-scroll": "^14.2.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-plugin-prismjs": "^1.0.2"
|
"babel-plugin-prismjs": "^2.0.1",
|
||||||
|
"babel-preset-gatsby": "^0.2.27",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-plugin-import": "^2.20.0"
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
}
|
}
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
const neatgrid = require('postcss-neat');
|
|
||||||
const nestedcss = require('postcss-nested');
|
|
||||||
// const colorfunctions = require('postcss-colour-functions');
|
|
||||||
const hdBackgrounds = require('postcss-at2x');
|
|
||||||
const cssextend = require('postcss-simple-extend');
|
|
||||||
const cssvars = require('postcss-simple-vars-async');
|
|
||||||
|
|
||||||
const styleVariables = require('./src/theme');
|
|
||||||
|
|
||||||
module.exports = () => ({
|
|
||||||
plugins: [
|
|
||||||
neatgrid(),
|
|
||||||
nestedcss(),
|
|
||||||
// colorfunctions(),
|
|
||||||
hdBackgrounds(),
|
|
||||||
cssextend(),
|
|
||||||
cssvars({ variables: styleVariables }),
|
|
||||||
],
|
|
||||||
});
|
|
@ -5,16 +5,9 @@ import Prism from 'prismjs';
|
|||||||
import { BlogPostTemplate } from '../templates/blog-post';
|
import { BlogPostTemplate } from '../templates/blog-post';
|
||||||
import { DocsTemplate } from '../templates/doc-page';
|
import { DocsTemplate } from '../templates/doc-page';
|
||||||
import WidgetDoc from '../components/widget-doc';
|
import WidgetDoc from '../components/widget-doc';
|
||||||
import Release from '../components/release';
|
|
||||||
import WhatsNew from '../components/whats-new';
|
import WhatsNew from '../components/whats-new';
|
||||||
import Notification from '../components/notification';
|
import Notification from '../components/notification';
|
||||||
import Community from '../components/community';
|
import Community from '../components/community';
|
||||||
import '../css/imports/hero.css';
|
|
||||||
import '../css/imports/docs.css';
|
|
||||||
import '../css/imports/whatsnew.css';
|
|
||||||
import '../css/imports/header.css';
|
|
||||||
import '../css/imports/collab.css';
|
|
||||||
import '../css/imports/community.css';
|
|
||||||
|
|
||||||
const withHighlight = WrappedComponent =>
|
const withHighlight = WrappedComponent =>
|
||||||
class Highlight extends React.Component {
|
class Highlight extends React.Component {
|
||||||
@ -70,16 +63,15 @@ const WidgetDocPreview = ({ entry, widgetFor }) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const ReleasePreview = ({ entry }) => (
|
const ReleasePreview = ({ entry }) => (
|
||||||
<WhatsNew>
|
<WhatsNew
|
||||||
{entry.getIn(['data', 'updates']).map((release, idx) => (
|
updates={[
|
||||||
<Release
|
entry.getIn(['data', 'updates']).map(release => ({
|
||||||
key={idx}
|
version: release.get('version'),
|
||||||
version={release.get('version')}
|
date: dayjs(release.get('date')).format('MMMM D, YYYY'),
|
||||||
date={dayjs(release.get('date')).format('MMMM D, YYYY')}
|
description: release.get('description'),
|
||||||
description={release.get('description')}
|
})),
|
||||||
/>
|
]}
|
||||||
))}
|
/>
|
||||||
</WhatsNew>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const NotificationPreview = ({ entry }) =>
|
const NotificationPreview = ({ entry }) =>
|
||||||
|
34
website/src/components/button.js
Normal file
34
website/src/components/button.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { css } from '@emotion/core';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const Button = styled.button`
|
||||||
|
display: inline-block;
|
||||||
|
background-image: linear-gradient(0deg, #97bf2f 14%, #c9fa4b 94%);
|
||||||
|
color: ${theme.colors.darkGray};
|
||||||
|
border-radius: ${theme.radii[1]};
|
||||||
|
font-size: ${theme.fontsize[3]};
|
||||||
|
font-weight: 700;
|
||||||
|
padding: ${theme.space[2]} ${theme.space[3]};
|
||||||
|
border: 2px solid ${theme.colors.darkGreen};
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
${p => p.block && css`
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
`};
|
||||||
|
|
||||||
|
${p => p.outline && css`
|
||||||
|
background: none;
|
||||||
|
font-weight: 500;
|
||||||
|
`};
|
||||||
|
|
||||||
|
${p => p.active && css`
|
||||||
|
background: ${theme.colors.darkGreen};
|
||||||
|
color: white;
|
||||||
|
`};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Button;
|
18
website/src/components/chat-button.js
Normal file
18
website/src/components/chat-button.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
const ChatLink = styled.a`
|
||||||
|
z-index: 100;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ChatButton = () => (
|
||||||
|
<ChatLink href="/chat">
|
||||||
|
<img src="/img/slack.svg" />
|
||||||
|
</ChatLink>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default ChatButton;
|
56
website/src/components/community-channels-list.js
Normal file
56
website/src/components/community-channels-list.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const StyledCommunityChannelsList = styled.ul`
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
font-weight: inherit;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:active,
|
||||||
|
&:hover {
|
||||||
|
&:before {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
display: none;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: ${theme.colors.darkGreen};
|
||||||
|
left: -16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CommunityChannelsList = ({ channels }) => (
|
||||||
|
<StyledCommunityChannelsList>
|
||||||
|
{channels.map(({ title, description, url }, idx) => (
|
||||||
|
<li key={idx}>
|
||||||
|
<a href={url}>
|
||||||
|
<strong>{title}</strong>
|
||||||
|
<p>{description}</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</StyledCommunityChannelsList>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default CommunityChannelsList;
|
32
website/src/components/container.js
Normal file
32
website/src/components/container.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
|
import { mq } from '../utils';
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
max-width: 1280px;
|
||||||
|
padding-left: ${theme.space[4]};
|
||||||
|
padding-right: ${theme.space[4]};
|
||||||
|
|
||||||
|
${p =>
|
||||||
|
p.size === 'sm' &&
|
||||||
|
css`
|
||||||
|
max-width: 800px;
|
||||||
|
`};
|
||||||
|
|
||||||
|
${p =>
|
||||||
|
p.size === 'md' &&
|
||||||
|
css`
|
||||||
|
max-width: 1024px;
|
||||||
|
`};
|
||||||
|
|
||||||
|
${mq[3]} {
|
||||||
|
padding-left: ${theme.space[5]};
|
||||||
|
padding-right: ${theme.space[5]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Container;
|
@ -1,67 +1,101 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { useState } from 'react';
|
||||||
import Link from 'gatsby-link';
|
import { Link } from 'gatsby';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
/**
|
import Button from './button';
|
||||||
* Manually get table of contents since tableOfContents from markdown
|
import TableOfContents from './table-of-contents';
|
||||||
* nodes have code added.
|
import { mq } from '../utils';
|
||||||
*
|
import theme from '../theme';
|
||||||
* https://github.com/gatsbyjs/gatsby/issues/5436
|
|
||||||
*/
|
const Menu = styled.nav`
|
||||||
class TableOfContents extends Component {
|
margin-bottom: ${theme.space[5]};
|
||||||
state = {
|
`;
|
||||||
headings: [],
|
|
||||||
|
const MenuBtn = styled(Button)`
|
||||||
|
${mq[1]} {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MenuContent = styled.div`
|
||||||
|
display: ${p => (p.isOpen ? 'block' : 'none')};
|
||||||
|
background: white;
|
||||||
|
padding: ${theme.space[3]};
|
||||||
|
|
||||||
|
${mq[1]} {
|
||||||
|
display: block;
|
||||||
|
background: transparent;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MenuSection = styled.div`
|
||||||
|
margin-bottom: ${theme.space[3]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SectionTitle = styled.h3`
|
||||||
|
font-size: ${theme.fontsize[4]};
|
||||||
|
margin-bottom: ${theme.space[2]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SectionList = styled.ul``;
|
||||||
|
|
||||||
|
const MenuItem = styled.li``;
|
||||||
|
|
||||||
|
const NavLink = styled(Link)`
|
||||||
|
display: block;
|
||||||
|
/* font-weight: $regular; */
|
||||||
|
font-size: ${theme.fontsize[3]};
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
line-height: ${theme.lineHeight[1]};
|
||||||
|
text-transform: capitalize;
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
padding: ${theme.space[2]} 0;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: ${theme.colors.darkGreen};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: ${theme.colors.darkGreen};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DocsNav = ({ items, location }) => {
|
||||||
|
const [isMenuOpen, setMenuOpen] = useState(false);
|
||||||
|
|
||||||
|
const toggleMenu = () => {
|
||||||
|
setMenuOpen(isOpen => !isOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
return (
|
||||||
const contentHeadings = document.querySelectorAll('.docs-content h2');
|
<Menu>
|
||||||
|
<MenuBtn onClick={toggleMenu} block>
|
||||||
const headings = [];
|
{isMenuOpen ? <span>×</span> : <span>☰</span>} {isMenuOpen ? 'Hide' : 'Show'}{' '}
|
||||||
contentHeadings.forEach(h => {
|
Navigation
|
||||||
headings.push({
|
</MenuBtn>
|
||||||
id: h.id,
|
<MenuContent isOpen={isMenuOpen}>
|
||||||
text: h.innerText,
|
{items.map(item => (
|
||||||
});
|
<MenuSection key={item.title}>
|
||||||
});
|
<SectionTitle>{item.title}</SectionTitle>
|
||||||
|
<SectionList>
|
||||||
this.setState({
|
{item.group.edges.map(({ node }) => (
|
||||||
headings,
|
<MenuItem key={node.fields.slug}>
|
||||||
});
|
<NavLink to={node.fields.slug} activeClassName="active">
|
||||||
}
|
{node.frontmatter.title}
|
||||||
|
</NavLink>
|
||||||
render() {
|
{location.pathname === node.fields.slug && <TableOfContents />}
|
||||||
const { headings } = this.state;
|
</MenuItem>
|
||||||
return (
|
))}
|
||||||
<ul className="nav-subsections">
|
</SectionList>
|
||||||
{headings.map(h => (
|
</MenuSection>
|
||||||
<li key={h.id}>
|
|
||||||
<a href={`#${h.id}`} className="subnav-link">
|
|
||||||
{h.text}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
))}
|
))}
|
||||||
</ul>
|
</MenuContent>
|
||||||
);
|
</Menu>
|
||||||
}
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
const DocsNav = ({ items, location }) => (
|
|
||||||
<nav className="docs-nav" id="docs-nav">
|
|
||||||
{items.map(item => (
|
|
||||||
<div className="docs-nav-section" key={item.title}>
|
|
||||||
<div className="docs-nav-section-title">{item.title}</div>
|
|
||||||
<ul className="docs-nav-section-list">
|
|
||||||
{item.group.edges.map(({ node }) => (
|
|
||||||
<li className="docs-nav-item" key={node.fields.slug}>
|
|
||||||
<Link to={node.fields.slug} className="nav-link" activeClassName="active">
|
|
||||||
{node.frontmatter.title}
|
|
||||||
</Link>
|
|
||||||
{location.pathname === node.fields.slug && <TableOfContents />}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</nav>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default DocsNav;
|
export default DocsNav;
|
||||||
|
|
||||||
|
export { NavLink };
|
||||||
|
@ -1,35 +1,56 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { useState, useEffect, memo } from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
import searchIcon from '../img/search.svg';
|
import searchIcon from '../img/search.svg';
|
||||||
|
|
||||||
class DocSearch extends Component {
|
const SearchForm = styled.form`
|
||||||
state = {
|
> span {
|
||||||
enabled: true,
|
width: 100%;
|
||||||
};
|
}
|
||||||
componentDidMount() {
|
`;
|
||||||
|
|
||||||
|
const SearchField = styled.input`
|
||||||
|
color: white;
|
||||||
|
font-size: ${theme.fontsize[3]};
|
||||||
|
border-radius: ${theme.radii[1]};
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
background-image: url(${searchIcon});
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: ${theme.space[2]} 50%;
|
||||||
|
border: 0;
|
||||||
|
appearance: none;
|
||||||
|
width: 100%;
|
||||||
|
padding: ${theme.space[2]};
|
||||||
|
padding-left: 30px;
|
||||||
|
outline: 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DocSearch = () => {
|
||||||
|
const [enabled, setEnabled] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
if (window.docsearch) {
|
if (window.docsearch) {
|
||||||
window.docsearch({
|
window.docsearch({
|
||||||
apiKey: '08d03dc80862e84c70c5a1e769b13019',
|
apiKey: '08d03dc80862e84c70c5a1e769b13019',
|
||||||
indexName: 'netlifycms',
|
indexName: 'netlifycms',
|
||||||
inputSelector: '.algolia-search',
|
inputSelector: '#algolia-search',
|
||||||
debug: false, // Set debug to true if you want to inspect the dropdown
|
debug: false, // Set debug to true if you want to inspect the dropdown
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({ enabled: false });
|
setEnabled(false);
|
||||||
}
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
if (!this.state.enabled) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
if (!enabled) {
|
||||||
<div className="utility-input">
|
return null;
|
||||||
<img src={searchIcon} alt="" />
|
|
||||||
<input type="search" placeholder="Search the docs" className="algolia-search" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export default DocSearch;
|
return (
|
||||||
|
<SearchForm>
|
||||||
|
<SearchField type="search" placeholder="Search the docs" id="algolia-search" />
|
||||||
|
</SearchForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(DocSearch);
|
||||||
|
@ -1,32 +1,44 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
const EditLink = ({ path }) => (
|
const EditLink = ({ path }) => (
|
||||||
<a
|
<div
|
||||||
className="edit-this-page"
|
css={css`
|
||||||
href={`https://github.com/netlify/netlify-cms/blob/master/website/content/${path}`}
|
float: right;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pencil {
|
||||||
|
fill: #7ca511;
|
||||||
|
}
|
||||||
|
`}
|
||||||
>
|
>
|
||||||
<svg
|
<a href={`https://github.com/netlify/netlify-cms/blob/master/website/content/${path}`}>
|
||||||
version="1.1"
|
<svg
|
||||||
id="pencil"
|
version="1.1"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
id="pencil"
|
||||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
x="0px"
|
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||||
y="0px"
|
x="0px"
|
||||||
width="14px"
|
y="0px"
|
||||||
height="14px"
|
width="14px"
|
||||||
viewBox="0 0 512 512"
|
height="14px"
|
||||||
enableBackground="new 0 0 512 512"
|
viewBox="0 0 512 512"
|
||||||
xmlSpace="preserve"
|
enableBackground="new 0 0 512 512"
|
||||||
>
|
xmlSpace="preserve"
|
||||||
<path
|
>
|
||||||
d="M398.875,248.875L172.578,475.187l-22.625-22.625L376.25,226.265L398.875,248.875z M308.375,158.39L82.063,384.687
|
<path
|
||||||
|
d="M398.875,248.875L172.578,475.187l-22.625-22.625L376.25,226.265L398.875,248.875z M308.375,158.39L82.063,384.687
|
||||||
l45.266,45.25L353.625,203.64L308.375,158.39z M263.094,113.125L36.828,339.437l22.625,22.625L285.75,135.765L263.094,113.125z
|
l45.266,45.25L353.625,203.64L308.375,158.39z M263.094,113.125L36.828,339.437l22.625,22.625L285.75,135.765L263.094,113.125z
|
||||||
M308.375,67.875L285.719,90.5L421.5,226.265l22.625-22.625L308.375,67.875z M376.25,0L331,45.25l135.75,135.766L512,135.781
|
M308.375,67.875L285.719,90.5L421.5,226.265l22.625-22.625L308.375,67.875z M376.25,0L331,45.25l135.75,135.766L512,135.781
|
||||||
L376.25,0z M32,453.5V480h26.5L32,453.5 M0,376.25L135.766,512H0V376.25L0,376.25z"
|
L376.25,0z M32,453.5V480h26.5L32,453.5 M0,376.25L135.766,512H0V376.25L0,376.25z"
|
||||||
/>
|
/>
|
||||||
</svg>{' '}
|
</svg>{' '}
|
||||||
Edit this page
|
Edit this page
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default EditLink;
|
export default EditLink;
|
||||||
|
126
website/src/components/event-box.js
Normal file
126
website/src/components/event-box.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import moment from 'moment';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import Markdownify from './markdownify';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const Root = styled.div`
|
||||||
|
text-align: center;
|
||||||
|
background: ${theme.colors.darkerGray};
|
||||||
|
background-image: linear-gradient(
|
||||||
|
-17deg,
|
||||||
|
${theme.colors.darkerGray} 17%,
|
||||||
|
${theme.colors.darkGray} 94%
|
||||||
|
);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 24px;
|
||||||
|
padding-top: 40px;
|
||||||
|
max-width: 446px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Title = styled.h2`
|
||||||
|
font-size: 36px;
|
||||||
|
color: white;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Cal = styled.div`
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
|
||||||
|
margin: 24px auto;
|
||||||
|
max-width: 250px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Month = styled.div`
|
||||||
|
background: ${theme.colors.green};
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Day = styled.div`
|
||||||
|
font-size: 104px;
|
||||||
|
line-height: 1.3;
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid ${theme.colors.gray};
|
||||||
|
border-top: none;
|
||||||
|
border-bottom-left-radius: 8px;
|
||||||
|
border-bottom-right-radius: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CalDates = styled.p`
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: ${theme.fontsize[4]};
|
||||||
|
margin-bottom: ${theme.space[3]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CalCta = styled.div``;
|
||||||
|
|
||||||
|
const EventBox = ({ title, cta }) => {
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [eventDate, setEventDate] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const eventbriteToken = 'C5PX65CJBVIXWWLNFKLO';
|
||||||
|
const eventbriteOrganiser = '14281996019';
|
||||||
|
|
||||||
|
const url = `https://www.eventbriteapi.com/v3/events/search/?token=${eventbriteToken}&organizer.id=${eventbriteOrganiser}&expand=venue%27`;
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
const eventDate = data.events[0].start.utc;
|
||||||
|
|
||||||
|
setEventDate(eventDate);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err); // eslint-disable-line no-console
|
||||||
|
// TODO: set state to show error message
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const eventDateMoment = moment(eventDate);
|
||||||
|
|
||||||
|
const offset = eventDateMoment.isDST() ? -7 : -8;
|
||||||
|
const month = eventDateMoment.format('MMMM');
|
||||||
|
const day = eventDateMoment.format('DD');
|
||||||
|
const datePrefix = eventDateMoment.format('dddd, MMMM Do');
|
||||||
|
const dateSuffix = eventDateMoment.utcOffset(offset).format('h a');
|
||||||
|
|
||||||
|
const ellip = <span>…</span>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Root>
|
||||||
|
<Title>{title}</Title>
|
||||||
|
<Cal>
|
||||||
|
<Month>{loading ? 'loading' : month}</Month>
|
||||||
|
<Day>{loading ? ellip : day}</Day>
|
||||||
|
</Cal>
|
||||||
|
<CalDates>
|
||||||
|
{loading ? (
|
||||||
|
ellip
|
||||||
|
) : (
|
||||||
|
<span>
|
||||||
|
{datePrefix} at {dateSuffix} PT
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</CalDates>
|
||||||
|
<CalCta>
|
||||||
|
<Markdownify source={cta} />
|
||||||
|
</CalCta>
|
||||||
|
</Root>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EventBox;
|
@ -1,71 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
class EventWidget extends Component {
|
|
||||||
state = {
|
|
||||||
loading: false,
|
|
||||||
eventDate: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const eventbriteToken = 'C5PX65CJBVIXWWLNFKLO';
|
|
||||||
const eventbriteOrganiser = '14281996019';
|
|
||||||
|
|
||||||
const url = `https://www.eventbriteapi.com/v3/events/search/?token=${eventbriteToken}&organizer.id=${eventbriteOrganiser}&expand=venue%27`;
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
loading: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
fetch(url)
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(data => {
|
|
||||||
const eventDate = data.events[0].start.utc;
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
eventDate,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err); // eslint-disable-line no-console
|
|
||||||
// TODO: set state to show error message
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
const { loading, eventDate } = this.state;
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return <span>Loading...</span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const eventDateMoment = moment(eventDate);
|
|
||||||
|
|
||||||
const offset = eventDateMoment.isDST() ? -7 : -8;
|
|
||||||
|
|
||||||
const month = eventDateMoment.format('MMMM');
|
|
||||||
const day = eventDateMoment.format('DD');
|
|
||||||
|
|
||||||
const datePrefix = eventDateMoment.format('dddd, MMMM Do');
|
|
||||||
const dateSuffix = eventDateMoment.utcOffset(offset).format('h a');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className="calendar">
|
|
||||||
<div className="month">{month}</div>
|
|
||||||
<div className="day">{day}</div>
|
|
||||||
</div>
|
|
||||||
<h3>
|
|
||||||
<strong>
|
|
||||||
{datePrefix} at {dateSuffix} PT
|
|
||||||
</strong>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EventWidget;
|
|
43
website/src/components/features.js
Normal file
43
website/src/components/features.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import Markdownify from './markdownify';
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const Box = styled.div`
|
||||||
|
margin-bottom: ${theme.space[5]};
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-bottom: ${theme.space[3]};
|
||||||
|
margin-left: -${theme.space[2]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Title = styled.h3`
|
||||||
|
color: ${p => (p.kind === 'light' ? theme.colors.white : theme.colors.gray)};
|
||||||
|
font-size: ${theme.fontsize[4]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Text = styled.p`
|
||||||
|
font-size: 18px;
|
||||||
|
a {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FeatureItem = ({ feature, description, imgpath, kind }) => (
|
||||||
|
<Box>
|
||||||
|
{imgpath && <img src={require(`../img/${imgpath}`)} alt="" />}
|
||||||
|
<Title kind={kind}>
|
||||||
|
<Markdownify source={feature} />
|
||||||
|
</Title>
|
||||||
|
<Text>
|
||||||
|
<Markdownify source={description} />
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Features = ({ items, kind }) =>
|
||||||
|
items.map(item => <FeatureItem kind={kind} {...item} key={item.feature} />);
|
||||||
|
|
||||||
|
export default Features;
|
@ -1,36 +1,96 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import '../css/imports/footer.css';
|
import Container from './container';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
import { mq } from '../utils';
|
||||||
|
|
||||||
|
const Root = styled.footer`
|
||||||
|
background: white;
|
||||||
|
padding-top: ${theme.space[4]};
|
||||||
|
padding-bottom: ${theme.space[5]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FooterGrid = styled.div`
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
${mq[2]} {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FooterButtons = styled.div`
|
||||||
|
margin-bottom: ${theme.space[3]};
|
||||||
|
${mq[2]} {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SocialButton = styled.a`
|
||||||
|
display: inline-block;
|
||||||
|
padding: ${theme.space[1]} ${theme.space[3]};
|
||||||
|
background-color: ${theme.colors.lightishGray};
|
||||||
|
color: white;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: ${theme.fontsize[2]};
|
||||||
|
border-radius: ${theme.radii[1]};
|
||||||
|
margin-right: ${theme.space[2]};
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:hover {
|
||||||
|
background-color: ${theme.colors.darkGreen};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Info = styled.div`
|
||||||
|
font-size: ${theme.fontsize[1]};
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
opacity: 0.5;
|
||||||
|
|
||||||
|
${mq[2]} {
|
||||||
|
padding-left: ${theme.space[4]};
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 700;
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const Footer = ({ buttons }) => (
|
const Footer = ({ buttons }) => (
|
||||||
<footer>
|
<Root>
|
||||||
<div className="contained">
|
<Container>
|
||||||
<div className="social-buttons">
|
<FooterGrid>
|
||||||
{buttons.map(btn => (
|
<FooterButtons>
|
||||||
<a href={btn.url} key={btn.url}>
|
{buttons.map(btn => (
|
||||||
{btn.name}
|
<SocialButton href={btn.url} key={btn.url}>
|
||||||
</a>
|
{btn.name}
|
||||||
))}
|
</SocialButton>
|
||||||
</div>
|
))}
|
||||||
<div className="footer-info">
|
</FooterButtons>
|
||||||
<p>
|
<Info>
|
||||||
<a
|
<p>
|
||||||
href="https://github.com/netlify/netlify-cms/blob/master/LICENSE"
|
<a
|
||||||
className="text-link"
|
href="https://github.com/netlify/netlify-cms/blob/master/LICENSE"
|
||||||
>
|
className="text-link"
|
||||||
Distributed under MIT License
|
>
|
||||||
</a>{' '}
|
Distributed under MIT License
|
||||||
·{' '}
|
</a>{' '}
|
||||||
<a
|
·{' '}
|
||||||
href="https://github.com/netlify/netlify-cms/blob/master/CODE_OF_CONDUCT.md"
|
<a
|
||||||
className="text-link"
|
href="https://github.com/netlify/netlify-cms/blob/master/CODE_OF_CONDUCT.md"
|
||||||
>
|
className="text-link"
|
||||||
Code of Conduct
|
>
|
||||||
</a>
|
Code of Conduct
|
||||||
</p>
|
</a>
|
||||||
</div>
|
</p>
|
||||||
</div>
|
</Info>
|
||||||
</footer>
|
</FooterGrid>
|
||||||
|
</Container>
|
||||||
|
</Root>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Footer;
|
export default Footer;
|
||||||
|
14
website/src/components/grid.js
Normal file
14
website/src/components/grid.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { mq } from '../utils';
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const Grid = styled.div`
|
||||||
|
${mq[2]} {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(${p => p.cols}, 1fr);
|
||||||
|
grid-gap: ${theme.space[7]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Grid;
|
@ -1,88 +1,215 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import Link from 'gatsby-link';
|
import { Link } from 'gatsby';
|
||||||
import classnames from 'classnames';
|
import styled from '@emotion/styled';
|
||||||
import { Location } from '@reach/router';
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
|
import GitHubButton from 'react-github-btn';
|
||||||
|
import Container from './container';
|
||||||
|
import Notifications from './notifications';
|
||||||
import DocSearch from './docsearch';
|
import DocSearch from './docsearch';
|
||||||
import GitHubButton from './github-button';
|
|
||||||
|
|
||||||
import logo from '../img/netlify-cms-logo.svg';
|
import logo from '../img/netlify-cms-logo.svg';
|
||||||
|
import searchIcon from '../img/search.svg';
|
||||||
|
|
||||||
import '../css/imports/header.css';
|
import theme from '../theme';
|
||||||
|
import { mq } from '../utils';
|
||||||
|
|
||||||
class Header extends Component {
|
const StyledHeader = styled.header`
|
||||||
state = {
|
background: ${theme.colors.darkerGray};
|
||||||
scrolled: false,
|
padding-top: ${theme.space[3]};
|
||||||
};
|
padding-bottom: ${theme.space[3]};
|
||||||
|
transition: background 0.2s ease, padding 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
|
||||||
async componentDidMount() {
|
${mq[2]} {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: ${theme.zIndexes.header};
|
||||||
|
|
||||||
|
${p =>
|
||||||
|
p.hasHeroBelow &&
|
||||||
|
!p.scrolled &&
|
||||||
|
css`
|
||||||
|
background: #2a2c24;
|
||||||
|
padding-top: ${theme.space[5]};
|
||||||
|
padding-bottom: ${theme.space[5]};
|
||||||
|
`};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const HeaderContainer = styled(Container)`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Logo = styled.div`
|
||||||
|
flex: 1 0 50%;
|
||||||
|
${mq[1]} {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-right: ${theme.space[5]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MenuActions = styled.div`
|
||||||
|
flex: 1 0 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
${mq[1]} {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MenuBtn = styled.button`
|
||||||
|
background: none;
|
||||||
|
border: 0;
|
||||||
|
color: white;
|
||||||
|
padding: ${theme.space[3]};
|
||||||
|
font-size: ${theme.fontsize[4]};
|
||||||
|
line-height: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SearchBtn = styled(MenuBtn)``;
|
||||||
|
|
||||||
|
const ToggleArea = styled.div`
|
||||||
|
display: ${p => (p.open ? 'block' : 'none')};
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: ${theme.space[3]};
|
||||||
|
|
||||||
|
${mq[1]} {
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SearchBox = styled(ToggleArea)`
|
||||||
|
${mq[1]} {
|
||||||
|
flex: 1;
|
||||||
|
max-width: 200px;
|
||||||
|
margin-right: ${theme.space[3]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Menu = styled(ToggleArea)`
|
||||||
|
${mq[1]} {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MenuList = styled.ul`
|
||||||
|
${mq[1]} {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MenuItem = styled.li`
|
||||||
|
margin-bottom: ${theme.space[3]};
|
||||||
|
${mq[1]} {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-right: ${theme.space[3]};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const NavLink = styled(Link)`
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Header = ({ hasHeroBelow }) => {
|
||||||
|
const [scrolled, setScrolled] = useState(false);
|
||||||
|
const [isNavOpen, setNavOpen] = useState(false);
|
||||||
|
const [isSearchOpen, setSearchOpen] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
// TODO: use raf to throttle events
|
// TODO: use raf to throttle events
|
||||||
window.addEventListener('scroll', this.handleScroll);
|
window.addEventListener('scroll', handleScroll);
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
return () => {
|
||||||
window.removeEventListener('scroll', this.handleScroll);
|
window.removeEventListener('scroll', handleScroll);
|
||||||
}
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
handleScroll = () => {
|
const handleScroll = () => {
|
||||||
const currentWindowPos = document.documentElement.scrollTop || document.body.scrollTop;
|
const currentWindowPos = document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
|
|
||||||
const scrolled = currentWindowPos > 0;
|
const scrolled = currentWindowPos > 0;
|
||||||
|
|
||||||
this.setState({
|
setScrolled(scrolled);
|
||||||
scrolled,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
const handleMenuBtnClick = () => {
|
||||||
const { scrolled } = this.state;
|
setNavOpen(s => !s);
|
||||||
|
setSearchOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
const handleSearchBtnClick = () => {
|
||||||
<Location>
|
setSearchOpen(s => !s);
|
||||||
{({ location }) => {
|
setNavOpen(false);
|
||||||
const isDocs = location.pathname.indexOf('docs') !== -1;
|
};
|
||||||
const isBlog = location.pathname.indexOf('blog') !== -1;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header
|
<StyledHeader scrolled={scrolled} id="header" hasHeroBelow={hasHeroBelow}>
|
||||||
id="header"
|
<Notifications />
|
||||||
className={classnames({
|
<HeaderContainer>
|
||||||
docs: isDocs,
|
<Logo>
|
||||||
blog: isBlog,
|
<Link to="/">
|
||||||
scrolled,
|
<img src={logo} alt="Netlify CMS logo" />
|
||||||
})}
|
</Link>
|
||||||
|
</Logo>
|
||||||
|
<MenuActions>
|
||||||
|
<SearchBtn onClick={handleSearchBtnClick}>
|
||||||
|
{isSearchOpen ? <span>×</span> : <img src={searchIcon} alt="search" />}
|
||||||
|
</SearchBtn>
|
||||||
|
<MenuBtn onClick={handleMenuBtnClick}>
|
||||||
|
{isNavOpen ? <span>×</span> : <span>☰</span>}
|
||||||
|
</MenuBtn>
|
||||||
|
</MenuActions>
|
||||||
|
<SearchBox open={isSearchOpen}>
|
||||||
|
<DocSearch />
|
||||||
|
</SearchBox>
|
||||||
|
<Menu open={isNavOpen}>
|
||||||
|
<MenuList>
|
||||||
|
<MenuItem
|
||||||
|
css={css`
|
||||||
|
margin-top: 8px;
|
||||||
|
`}
|
||||||
>
|
>
|
||||||
<div className="contained">
|
<GitHubButton
|
||||||
<div className="logo-container">
|
href="https://github.com/netlify/netlify-cms"
|
||||||
<Link to="/" className="logo">
|
data-icon="octicon-star"
|
||||||
<img src={logo} alt="Netlify CMS" />
|
data-show-count="true"
|
||||||
</Link>
|
aria-label="Star netlify/netlify-cms on GitHub"
|
||||||
<DocSearch />
|
>
|
||||||
</div>
|
Star
|
||||||
<div className="nav-container">
|
</GitHubButton>
|
||||||
<span className="gh-button">
|
</MenuItem>
|
||||||
<GitHubButton />
|
<MenuItem>
|
||||||
</span>
|
<NavLink to="/docs/intro/">Docs</NavLink>
|
||||||
<Link className="nav-link docs-link" to="/docs/intro/">
|
</MenuItem>
|
||||||
Docs
|
<MenuItem>
|
||||||
</Link>
|
<NavLink to="/docs/contributor-guide/">Contributing</NavLink>
|
||||||
<Link className="nav-link contributing-link" to="/docs/contributor-guide/">
|
</MenuItem>
|
||||||
Contributing
|
<MenuItem>
|
||||||
</Link>
|
<NavLink to="/community/">Community</NavLink>
|
||||||
<Link className="nav-link" to="/community/">
|
</MenuItem>
|
||||||
Community
|
<MenuItem>
|
||||||
</Link>
|
<NavLink to="/blog/">Blog</NavLink>
|
||||||
<Link className="nav-link" to="/blog/">
|
</MenuItem>
|
||||||
Blog
|
</MenuList>
|
||||||
</Link>
|
</Menu>
|
||||||
</div>
|
</HeaderContainer>
|
||||||
</div>
|
</StyledHeader>
|
||||||
</header>
|
);
|
||||||
);
|
};
|
||||||
}}
|
|
||||||
</Location>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Header;
|
export default Header;
|
||||||
|
16
website/src/components/hero-title.js
Normal file
16
website/src/components/hero-title.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
import theme from '../theme';
|
||||||
|
import { mq } from '../utils';
|
||||||
|
|
||||||
|
const HeroTitle = styled.h1`
|
||||||
|
color: ${theme.colors.green};
|
||||||
|
font-size: ${theme.fontsize[6]};
|
||||||
|
margin-bottom: ${theme.space[1]};
|
||||||
|
|
||||||
|
${mq[2]} {
|
||||||
|
font-size: ${theme.fontsize[7]};
|
||||||
|
margin-bottom: ${theme.space[2]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default HeroTitle;
|
36
website/src/components/home-section.js
Normal file
36
website/src/components/home-section.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import Container from './container';
|
||||||
|
import Page from './page';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const Header = styled.header`
|
||||||
|
text-align: center;
|
||||||
|
padding-top: ${theme.space[7]};
|
||||||
|
padding-bottom: ${theme.space[7]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Title = styled.h2`
|
||||||
|
font-size: ${theme.fontsize[6]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Text = styled.div`
|
||||||
|
max-width: 710px;
|
||||||
|
margin: 0 auto;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const HomeSection = ({ title, text, children, ...props }) => (
|
||||||
|
<Page as="section" {...props}>
|
||||||
|
<Container>
|
||||||
|
<Header>
|
||||||
|
<Title>{title}</Title>
|
||||||
|
{text && <Text>{text}</Text>}
|
||||||
|
</Header>
|
||||||
|
{children}
|
||||||
|
</Container>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default HomeSection;
|
@ -1,67 +1,53 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React from 'react';
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { graphql, StaticQuery } from 'gatsby';
|
import { graphql, StaticQuery } from 'gatsby';
|
||||||
|
import { ThemeProvider } from 'emotion-theming';
|
||||||
import Header from './header';
|
import Header from './header';
|
||||||
import Footer from './footer';
|
import Footer from './footer';
|
||||||
import Notification from './notification';
|
import GlobalStyles from '../global-styles';
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
import '../css/imports/base.css';
|
const LAYOUT_QUERY = graphql`
|
||||||
import '../css/imports/utilities.css';
|
query layoutQuery {
|
||||||
import '../css/imports/chat.css';
|
site {
|
||||||
|
siteMetadata {
|
||||||
const Layout = ({ children }) => {
|
title
|
||||||
return (
|
description
|
||||||
<StaticQuery
|
}
|
||||||
query={graphql`
|
}
|
||||||
query layoutQuery {
|
footer: file(relativePath: { regex: "/global/" }) {
|
||||||
site {
|
childDataYaml {
|
||||||
siteMetadata {
|
footer {
|
||||||
title
|
buttons {
|
||||||
description
|
url
|
||||||
}
|
name
|
||||||
}
|
|
||||||
footer: file(relativePath: { regex: "/global/" }) {
|
|
||||||
childDataYaml {
|
|
||||||
footer {
|
|
||||||
buttons {
|
|
||||||
url
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notifs: file(relativePath: { regex: "/notifications/" }) {
|
|
||||||
childDataYaml {
|
|
||||||
notifications {
|
|
||||||
published
|
|
||||||
loud
|
|
||||||
message
|
|
||||||
url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`}
|
}
|
||||||
>
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Layout = ({ hasPageHero, children }) => {
|
||||||
|
return (
|
||||||
|
<StaticQuery query={LAYOUT_QUERY}>
|
||||||
{data => {
|
{data => {
|
||||||
const { title, description } = data.site.siteMetadata;
|
const { title, description } = data.site.siteMetadata;
|
||||||
const notifs = data.notifs.childDataYaml.notifications.filter(notif => notif.published);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<ThemeProvider theme={theme}>
|
||||||
|
<GlobalStyles />
|
||||||
<Helmet defaultTitle={title} titleTemplate={`%s | ${title}`}>
|
<Helmet defaultTitle={title} titleTemplate={`%s | ${title}`}>
|
||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,700,900|Roboto+Mono:400,700"
|
||||||
|
/>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
{notifs.map((node, i) => (
|
<Header hasHeroBelow={hasPageHero} />
|
||||||
<Notification key={i} url={node.url} loud={node.loud}>
|
|
||||||
{node.message}
|
|
||||||
</Notification>
|
|
||||||
))}
|
|
||||||
<Header notifications={notifs} />
|
|
||||||
{children}
|
{children}
|
||||||
<Footer buttons={data.footer.childDataYaml.footer.buttons} />
|
<Footer buttons={data.footer.childDataYaml.footer.buttons} />
|
||||||
</Fragment>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</StaticQuery>
|
</StaticQuery>
|
||||||
|
10
website/src/components/lead.js
Normal file
10
website/src/components/lead.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
const Lead = styled.p`
|
||||||
|
font-size: 20px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
${p => p.light && 'color: white;'};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Lead;
|
132
website/src/components/markdown.js
Normal file
132
website/src/components/markdown.js
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const StyledMarkdown = styled.div`
|
||||||
|
> :first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
> :last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
line-height: ${theme.lineHeight[1]};
|
||||||
|
margin-top: 2em;
|
||||||
|
margin-bottom: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: ${theme.fontsize[6]};
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: ${theme.fontsize[5]};
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: ${theme.fontsize[4]};
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: ${theme.fontsize[3]};
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
margin-left: ${theme.space[3]};
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
p {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border: 0;
|
||||||
|
background: #f7f7f7;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 40px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr {
|
||||||
|
&:nth-child(odd) {
|
||||||
|
background: #fdfdfd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
border-radius: ${theme.radii[2]};
|
||||||
|
margin-bottom: ${theme.space[4]};
|
||||||
|
margin-top: ${theme.space[4]};
|
||||||
|
}
|
||||||
|
|
||||||
|
pre > code {
|
||||||
|
font-size: ${theme.fontsize[2]};
|
||||||
|
line-height: ${theme.lineHeight[0]};
|
||||||
|
}
|
||||||
|
|
||||||
|
*:not(pre) > code {
|
||||||
|
color: inherit;
|
||||||
|
background: #e6e6e6;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: ${theme.fontsize[2]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Markdown = ({ html }) => {
|
||||||
|
return <StyledMarkdown dangerouslySetInnerHTML={{ __html: html }} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Markdown;
|
10
website/src/components/meta-info.js
Normal file
10
website/src/components/meta-info.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const MetaInfo = styled.p`
|
||||||
|
font-size: ${theme.fontsize[2]};
|
||||||
|
margin-bottom: ${theme.space[4]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default MetaInfo;
|
@ -1,52 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
import { Link } from 'gatsby';
|
|
||||||
|
|
||||||
class MobileNav extends Component {
|
|
||||||
state = {
|
|
||||||
isOpen: false,
|
|
||||||
};
|
|
||||||
toggleNav = () => {
|
|
||||||
this.setState({
|
|
||||||
isOpen: !this.state.isOpen,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
render() {
|
|
||||||
const { items } = this.props;
|
|
||||||
const { isOpen } = this.state;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mobile-docs-nav">
|
|
||||||
<button className="btn-primary mobile-docs-nav-btn" onClick={this.toggleNav}>
|
|
||||||
{isOpen ? <span>×</span> : <span>☰</span>} {isOpen ? 'Hide' : 'Show'}{' '}
|
|
||||||
Navigation
|
|
||||||
</button>
|
|
||||||
{isOpen && (
|
|
||||||
<nav className="mobile-docs-nav-content">
|
|
||||||
<ul className="mobile-docs-nav-list">
|
|
||||||
{items.map(item => (
|
|
||||||
<li key={item.title} className="mobile-docs-nav-item">
|
|
||||||
{item.title}
|
|
||||||
<ul className="mobile-docs-nav-list">
|
|
||||||
{item.group.edges.map(({ node }) => (
|
|
||||||
<li key={node.fields.slug} className="mobile-docs-nav-item">
|
|
||||||
<Link
|
|
||||||
to={node.fields.slug}
|
|
||||||
className="mobile-docs-nav-link"
|
|
||||||
onClick={this.toggleNav}
|
|
||||||
>
|
|
||||||
{node.frontmatter.title}
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MobileNav;
|
|
@ -1,10 +1,46 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import cn from 'classnames';
|
import styled from '@emotion/styled';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const Notif = styled.a`
|
||||||
|
background-color: ${theme.colors.darkerGray};
|
||||||
|
color: white;
|
||||||
|
display: block;
|
||||||
|
padding: ${theme.space[2]} ${theme.space[3]};
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
${p =>
|
||||||
|
p.loud &&
|
||||||
|
css`
|
||||||
|
background-color: ${theme.colors.green};
|
||||||
|
color: ${theme.colors.darkerGray};
|
||||||
|
`}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-style: normal;
|
||||||
|
color: #8b8b8b;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup,
|
||||||
|
sub {
|
||||||
|
font-size: initial;
|
||||||
|
vertical-align: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-link {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: ${theme.colors.green};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const Notification = ({ url, loud, children }) => (
|
const Notification = ({ url, loud, children }) => (
|
||||||
<a href={url} className={cn('notification', { 'notification-loud': loud })}>
|
<Notif href={url} loud={loud}>
|
||||||
{children}
|
{children}
|
||||||
</a>
|
</Notif>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Notification;
|
export default Notification;
|
||||||
|
34
website/src/components/notifications.js
Normal file
34
website/src/components/notifications.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { graphql, StaticQuery } from 'gatsby';
|
||||||
|
|
||||||
|
import Notification from './notification';
|
||||||
|
|
||||||
|
const NOTIFS_QUERY = graphql`
|
||||||
|
query notifs {
|
||||||
|
file(relativePath: { regex: "/notifications/" }) {
|
||||||
|
childDataYaml {
|
||||||
|
notifications {
|
||||||
|
published
|
||||||
|
loud
|
||||||
|
message
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Notifications = () => (
|
||||||
|
<StaticQuery query={NOTIFS_QUERY}>
|
||||||
|
{data => {
|
||||||
|
const notifs = data.file.childDataYaml.notifications.filter(notif => notif.published);
|
||||||
|
return notifs.map((node, i) => (
|
||||||
|
<Notification key={i} url={node.url} loud={node.loud}>
|
||||||
|
{node.message}
|
||||||
|
</Notification>
|
||||||
|
));
|
||||||
|
}}
|
||||||
|
</StaticQuery>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Notifications;
|
29
website/src/components/page-hero.js
Normal file
29
website/src/components/page-hero.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
|
import Container from './container';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
import { mq } from '../utils';
|
||||||
|
|
||||||
|
const PageHero = ({ children }) => (
|
||||||
|
<section
|
||||||
|
css={css`
|
||||||
|
background: ${theme.colors.darkerGray};
|
||||||
|
background-image: linear-gradient(to bottom, #2a2c24 0%, ${theme.colors.darkerGray} 20%);
|
||||||
|
color: ${theme.colors.blueGray};
|
||||||
|
position: relative;
|
||||||
|
padding-top: ${theme.space[6]};
|
||||||
|
padding-bottom: ${theme.space[6]};
|
||||||
|
|
||||||
|
${mq[3]} {
|
||||||
|
padding-top: ${theme.space[6]};
|
||||||
|
padding-bottom: ${theme.space[8]};
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<Container>{children}</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default PageHero;
|
16
website/src/components/page.js
Normal file
16
website/src/components/page.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
import { mq } from '../utils';
|
||||||
|
|
||||||
|
const Page = styled.div`
|
||||||
|
padding-top: ${theme.space[5]};
|
||||||
|
padding-bottom: ${theme.space[5]};
|
||||||
|
|
||||||
|
${mq[1]} {
|
||||||
|
padding-top: ${theme.space[6]};
|
||||||
|
padding-bottom: ${theme.space[6]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Page;
|
@ -1,23 +1,67 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
import Markdownify from '../components/markdownify';
|
import Markdownify from '../components/markdownify';
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const ReleaseLink = styled.a`
|
||||||
|
color: white;
|
||||||
|
display: block;
|
||||||
|
padding: ${theme.space[2]} ${theme.space[3]};
|
||||||
|
border-radius: ${theme.radii[1]};
|
||||||
|
height: 100%;
|
||||||
|
&:hover {
|
||||||
|
background: ${theme.colors.darkGray};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Version = styled.span`
|
||||||
|
background: ${theme.colors.shadeBlue};
|
||||||
|
font-size: ${theme.fontsize[1]};
|
||||||
|
padding: 0 ${theme.space[1]};
|
||||||
|
border-radius: ${theme.radii[1]};
|
||||||
|
font-weight: 700;
|
||||||
|
margin-right: ${theme.space[2]};
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
`;
|
||||||
|
|
||||||
const Release = ({ version, versionPrevious, date, description, url }) => {
|
const Release = ({ version, versionPrevious, date, description, url }) => {
|
||||||
const displayDate = moment(date).format('MMMM D, YYYY');
|
const displayDate = moment(date).format('MMMM D, YYYY');
|
||||||
const defaultUrl = `https://github.com/netlify/netlify-cms/compare/netlify-cms@${versionPrevious}...netlify-cms@${version}`;
|
const defaultUrl = `https://github.com/netlify/netlify-cms/compare/netlify-cms@${versionPrevious}...netlify-cms@${version}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a href={url || defaultUrl} key={version}>
|
<li
|
||||||
<li>
|
css={css`
|
||||||
<div className="update-metadata">
|
flex: 1;
|
||||||
<span className="update-version">{version}</span>
|
`}
|
||||||
<span className="update-date">{displayDate}</span>
|
>
|
||||||
|
<ReleaseLink href={url || defaultUrl}>
|
||||||
|
<div
|
||||||
|
css={css`
|
||||||
|
margin-bottom: ${theme.space[1]};
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<Version>{version}</Version>
|
||||||
|
<span
|
||||||
|
css={css`
|
||||||
|
font-size: ${theme.fontsize[1]};
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{displayDate}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="update-description">
|
<span
|
||||||
|
css={css`
|
||||||
|
font-size: ${theme.fontsize[2]};
|
||||||
|
`}
|
||||||
|
>
|
||||||
<Markdownify source={description} />
|
<Markdownify source={description} />
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</ReleaseLink>
|
||||||
</a>
|
</li>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
23
website/src/components/section-label.js
Normal file
23
website/src/components/section-label.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const SectionLabel = styled.h3`
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
font-size: ${theme.fontsize[1]};
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 1.5px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-bottom: ${theme.space[4]};
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
background: ${theme.colors.darkGreen};
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
height: 2px;
|
||||||
|
margin-top: 5px;
|
||||||
|
width: ${theme.space[5]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default SectionLabel;
|
22
website/src/components/sidebar-layout.js
Normal file
22
website/src/components/sidebar-layout.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
|
import Page from './page';
|
||||||
|
import { mq } from '../utils';
|
||||||
|
|
||||||
|
const SidebarLayout = ({ sidebar, children }) => (
|
||||||
|
<Page
|
||||||
|
css={css`
|
||||||
|
${mq[1]} {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 300px 1fr;
|
||||||
|
grid-gap: 2rem;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<div>{sidebar}</div>
|
||||||
|
<div>{children}</div>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default SidebarLayout;
|
59
website/src/components/table-of-contents.js
Normal file
59
website/src/components/table-of-contents.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
|
const TocList = styled.ol`
|
||||||
|
margin: ${theme.space[2]} 0;
|
||||||
|
padding-left: ${theme.space[3]};
|
||||||
|
border-left: 2px solid ${theme.colors.lightestGray};
|
||||||
|
list-style-type: none;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TocLink = styled.a`
|
||||||
|
display: block;
|
||||||
|
font-size: ${theme.fontsize[2]};
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
transition: color 0.2s;
|
||||||
|
line-height: ${theme.lineHeight[1]};
|
||||||
|
margin: ${theme.space[2]} 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: ${theme.colors.darkGreen};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maually get table of contents since tableOfContents from markdown
|
||||||
|
* nodes have code added.
|
||||||
|
*
|
||||||
|
* https://github.com/gatsbyjs/gatsby/issues/5436
|
||||||
|
*/
|
||||||
|
const TableOfContents = () => {
|
||||||
|
const [headings, setHeadings] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const contentHeadings = document.querySelectorAll('[data-docs-content] h2');
|
||||||
|
const headings = [];
|
||||||
|
contentHeadings.forEach(h => {
|
||||||
|
headings.push({
|
||||||
|
id: h.id,
|
||||||
|
text: h.innerText,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
setHeadings(headings);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TocList>
|
||||||
|
{headings.map(h => (
|
||||||
|
<li key={h.id}>
|
||||||
|
<TocLink href={`#${h.id}`}>{h.text}</TocLink>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</TocList>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TableOfContents;
|
@ -1,7 +1,65 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
import screenshotEditor from '../img/screenshot-editor.jpg';
|
import screenshotEditor from '../img/screenshot-editor.jpg';
|
||||||
|
|
||||||
|
const VideoLink = styled.a`
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
div {
|
||||||
|
background-color: ${theme.colors.blue};
|
||||||
|
box-shadow: 0 6px 18px 0 rgba(0, 0, 0, 0.15), 0 2px 6px 0 rgba(0, 0, 0, 0.3);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
svg {
|
||||||
|
fill: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
div {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
iframe {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: ${theme.radii[2]};
|
||||||
|
box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.15), 0 3px 9px 0 rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const VideoButton = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
margin: auto;
|
||||||
|
color: ${theme.colors.blue};
|
||||||
|
background-color: rgba(255, 255, 255, 0.85);
|
||||||
|
box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.05), 0 1px 3px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
border-radius: 100px;
|
||||||
|
transition: 0.1s;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
position: absolute;
|
||||||
|
left: 30px;
|
||||||
|
top: 24px;
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
fill: #3a69c7;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We should be able to import complete inline svg's rather than base64, this
|
* We should be able to import complete inline svg's rather than base64, this
|
||||||
* component is a stopgap for now. Source in '../img/play.svg'.
|
* component is a stopgap for now. Source in '../img/play.svg'.
|
||||||
@ -16,45 +74,35 @@ const PlayIcon = ({ className }) => (
|
|||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
class VideoEmbed extends Component {
|
const VideoEmbed = () => {
|
||||||
state = {
|
const [toggled, setToggled] = useState(false);
|
||||||
toggled: false,
|
|
||||||
};
|
|
||||||
toggleVideo = () => {
|
|
||||||
this.setState({
|
|
||||||
toggled: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
render() {
|
|
||||||
const { toggled } = this.state;
|
|
||||||
|
|
||||||
const embedcode = (
|
const toggleVideo = () => setToggled(true);
|
||||||
<iframe
|
|
||||||
width={560}
|
|
||||||
height={315}
|
|
||||||
src="https://www.youtube-nocookie.com/embed/p6h-rYSVX90?rel=0&showinfo=0&autoplay=1"
|
|
||||||
frameBorder={0}
|
|
||||||
allow="autoplay; encrypted-media"
|
|
||||||
allowFullScreen
|
|
||||||
title="video_embed"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const imgPlaceholder = (
|
const embedcode = (
|
||||||
<img src={screenshotEditor} className="responsive" alt="editor video screenshot" />
|
<iframe
|
||||||
);
|
title="Netlify CMS video"
|
||||||
|
width={560}
|
||||||
|
height={315}
|
||||||
|
src="https://www.youtube-nocookie.com/embed/p6h-rYSVX90?rel=0&showinfo=0&autoplay=1"
|
||||||
|
frameBorder={0}
|
||||||
|
allow="autoplay; encrypted-media"
|
||||||
|
allowFullScreen
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
const imgPlaceholder = <img src={screenshotEditor} alt="Netlify CMS editor" />;
|
||||||
<div className="hero-graphic" onClick={this.toggleVideo}>
|
|
||||||
{toggled ? embedcode : imgPlaceholder}
|
return (
|
||||||
{!toggled && (
|
<VideoLink onClick={toggleVideo}>
|
||||||
<div className="hero-videolink">
|
{toggled ? embedcode : imgPlaceholder}
|
||||||
<PlayIcon className="hero-videolink-arrow" />
|
{!toggled && (
|
||||||
</div>
|
<VideoButton>
|
||||||
)}
|
<PlayIcon />
|
||||||
</div>
|
</VideoButton>
|
||||||
);
|
)}
|
||||||
}
|
</VideoLink>
|
||||||
}
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default VideoEmbed;
|
export default VideoEmbed;
|
||||||
|
@ -1,10 +1,26 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
const WhatsNew = ({ children }) => (
|
import Container from './container';
|
||||||
<section className="whatsnew">
|
import Release from './release';
|
||||||
<div className="contained">
|
import Grid from './grid';
|
||||||
<ol>{children}</ol>
|
import theme from '../theme';
|
||||||
</div>
|
|
||||||
|
const WhatsNew = ({ updates }) => (
|
||||||
|
<section
|
||||||
|
css={css`
|
||||||
|
background: ${theme.colors.lightishGray};
|
||||||
|
padding-top: ${theme.space[6]};
|
||||||
|
padding-bottom: ${theme.space[5]};
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<Container>
|
||||||
|
<Grid as="ol" cols={3}>
|
||||||
|
{updates.slice(0, 3).map((item, idx) => (
|
||||||
|
<Release {...item} versionPrevious={updates[idx + 1].version} key={item.version} />
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
|
||||||
|
|
||||||
const WidgetDoc = ({ visible, label, body, html }) => (
|
import Markdown from './markdown';
|
||||||
<div className={classnames('widget', { widget_open: visible })}>
|
|
||||||
<h3>{label}</h3>
|
const WidgetDoc = ({ visible, label, body, html }) => {
|
||||||
{body ? body : <div dangerouslySetInnerHTML={{ __html: html }} />}
|
if (!visible) {
|
||||||
</div>
|
return null;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>{label}</h3>
|
||||||
|
<Markdown html={body || html} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default WidgetDoc;
|
export default WidgetDoc;
|
||||||
|
@ -1,79 +1,76 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import classnames from 'classnames';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import WidgetDoc from './widget-doc';
|
import WidgetDoc from './widget-doc';
|
||||||
|
import Button from './button';
|
||||||
|
|
||||||
import '../css/imports/widgets.css';
|
import theme from '../theme';
|
||||||
|
|
||||||
class Widgets extends Component {
|
const WidgetsNav = styled.nav`
|
||||||
state = {
|
margin-bottom: 1rem;
|
||||||
currentWidget: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
> button {
|
||||||
const { widgets } = this.props;
|
margin-right: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const WidgetsContent = styled.div`
|
||||||
|
background: ${theme.colors.lightGray};
|
||||||
|
padding: ${theme.space[3]};
|
||||||
|
border-radius: 4px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Widgets = ({ widgets }) => {
|
||||||
|
const [currentWidget, setWidget] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
const hash = window.location.hash ? window.location.hash.replace('#', '') : '';
|
const hash = window.location.hash ? window.location.hash.replace('#', '') : '';
|
||||||
|
|
||||||
const widgetsContainHash = widgets.edges.some(w => w.node.frontmatter.title === hash);
|
const widgetsContainHash = widgets.edges.some(w => w.node.frontmatter.title === hash);
|
||||||
|
|
||||||
if (widgetsContainHash) {
|
if (widgetsContainHash) {
|
||||||
return this.setState({
|
return setWidget(hash);
|
||||||
currentWidget: hash,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
setWidget(widgets.edges[0].node.frontmatter.title);
|
||||||
currentWidget: widgets.edges[0].node.frontmatter.title,
|
}, []);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleWidgetChange = (event, title) => {
|
const handleWidgetChange = (event, title) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.setState(
|
|
||||||
{
|
setWidget(title);
|
||||||
currentWidget: title,
|
|
||||||
},
|
window.history.pushState(null, null, `#${title}`);
|
||||||
() => {
|
|
||||||
window.history.pushState(null, null, `#${title}`);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const { widgets } = this.props;
|
<section>
|
||||||
const { currentWidget } = this.state;
|
<WidgetsNav>
|
||||||
|
{widgets.edges.map(({ node }) => {
|
||||||
return (
|
const { label, title } = node.frontmatter;
|
||||||
<div>
|
return (
|
||||||
<section className="widgets">
|
<Button
|
||||||
<div className="widgets__cloud">
|
key={title}
|
||||||
{widgets.edges.map(({ node }) => {
|
active={currentWidget === title}
|
||||||
const { label, title } = node.frontmatter;
|
onClick={event => handleWidgetChange(event, title)}
|
||||||
return (
|
outline
|
||||||
<button
|
>
|
||||||
key={title}
|
{label}
|
||||||
className={classnames('widgets__item', {
|
</Button>
|
||||||
widgets__item_active: currentWidget === title,
|
);
|
||||||
})}
|
})}
|
||||||
onClick={event => this.handleWidgetChange(event, title)}
|
</WidgetsNav>
|
||||||
>
|
<WidgetsContent>
|
||||||
{label}
|
{widgets.edges.map(({ node }) => {
|
||||||
</button>
|
const { frontmatter, html } = node;
|
||||||
);
|
const { title, label } = frontmatter;
|
||||||
})}
|
const isVisible = currentWidget === title;
|
||||||
</div>
|
return <WidgetDoc key={label} visible={isVisible} label={label} html={html} />;
|
||||||
<div className="widgets__container">
|
})}
|
||||||
{widgets.edges.map(({ node }) => {
|
</WidgetsContent>
|
||||||
const { frontmatter, html } = node;
|
</section>
|
||||||
const { title, label } = frontmatter;
|
);
|
||||||
const isVisible = currentWidget === title;
|
};
|
||||||
return <WidgetDoc key={label} visible={isVisible} label={label} html={html} />;
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Widgets;
|
export default Widgets;
|
||||||
|
@ -1,169 +0,0 @@
|
|||||||
@import url(
|
|
||||||
https://fonts.googleapis.com/css?family=Roboto:400,
|
|
||||||
100,
|
|
||||||
100italic,
|
|
||||||
300,
|
|
||||||
300italic,
|
|
||||||
400italic,
|
|
||||||
500,
|
|
||||||
700,
|
|
||||||
900|Roboto+Mono:400,
|
|
||||||
700
|
|
||||||
);
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: $shadeBlue;
|
|
||||||
color: $grey;
|
|
||||||
font-family: $roboto;
|
|
||||||
margin: 0;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100vh;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.page {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: $bold;
|
|
||||||
font-size: 36px;
|
|
||||||
line-height: 48px;
|
|
||||||
margin: 0 0 $small 0;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
font-size: 42px;
|
|
||||||
line-height: 56px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-family: $roboto;
|
|
||||||
font-size: 36px;
|
|
||||||
font-weight: $bold;
|
|
||||||
color: $darkGrey;
|
|
||||||
margin-bottom: $tiny;
|
|
||||||
|
|
||||||
&.subhead {
|
|
||||||
font-weight: $regular;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-family: $roboto;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: $bold;
|
|
||||||
line-height: 26px;
|
|
||||||
padding-bottom: $micro;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p,
|
|
||||||
ul {
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 26px;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: $darkGreen;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: $bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
margin: $tiny 0 $tiny $small;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contained {
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: $display;
|
|
||||||
padding: 0 $small;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
padding: 0 $medium;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*[class^='btn-'] {
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: inline-block;
|
|
||||||
font-family: $roboto;
|
|
||||||
font-size: $tiny;
|
|
||||||
font-weight: $bold;
|
|
||||||
margin: 0;
|
|
||||||
padding: $tiny $small;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: -40%;
|
|
||||||
left: -210%;
|
|
||||||
width: 200%;
|
|
||||||
height: 200%;
|
|
||||||
opacity: 0;
|
|
||||||
transform: rotate(30deg);
|
|
||||||
background: rgba(255, 255, 255, 0.2);
|
|
||||||
background: linear-gradient(
|
|
||||||
to right,
|
|
||||||
rgba(255, 255, 255, 0.2) 0%,
|
|
||||||
rgba(255, 255, 255, 0.2) 77%,
|
|
||||||
rgba(255, 255, 255, 0.6) 92%,
|
|
||||||
rgba(255, 255, 255, 0) 100%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover:after {
|
|
||||||
opacity: 1;
|
|
||||||
left: 110%;
|
|
||||||
transition-property: left, opacity;
|
|
||||||
transition-duration: 0.6s, 0.1s;
|
|
||||||
transition-timing-function: ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active:after {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
padding: $micro $tiny;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
background-image: linear-gradient(0deg, $lightGreen 14%, $green 94%);
|
|
||||||
color: $darkerGrey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-secondary {
|
|
||||||
border: 1px solid white;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
line-height: 1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fixes overflowing code example in widgets */
|
|
||||||
.widget pre {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code,
|
|
||||||
code {
|
|
||||||
font-family: 'Roboto Mono', monospace !important;
|
|
||||||
font-size: 80%;
|
|
||||||
text-transform: none;
|
|
||||||
line-height: 1 !important;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
.chat-button {
|
|
||||||
z-index: 100;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 10px;
|
|
||||||
right: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
.collab,
|
|
||||||
.community-channels {
|
|
||||||
margin: $medium $tiny;
|
|
||||||
|
|
||||||
@media screen and (min-width: $mobile) {
|
|
||||||
margin: $large auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.collab {
|
|
||||||
h1 {
|
|
||||||
margin-bottom: $small;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@media screen and (min-width: $mobile) {
|
|
||||||
margin-bottom: $large;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.collab-graphic {
|
|
||||||
@media screen and (min-width: $mobile) {
|
|
||||||
@neat-span-columns 4;
|
|
||||||
@neat-shift 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: $medium;
|
|
||||||
|
|
||||||
@media screen and (min-width: $mobile) {
|
|
||||||
margin-top: 0;
|
|
||||||
text-align: left;
|
|
||||||
@neat-span-columns 5;
|
|
||||||
@neat-shift 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
margin-top: $medium;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.community-channels {
|
|
||||||
padding-bottom: $xl;
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
.section-label:not(:first-child) {
|
|
||||||
margin-top: $large;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: $darkGreen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.community-channels-list {
|
|
||||||
margin-left: 0;
|
|
||||||
|
|
||||||
li {
|
|
||||||
list-style-type: none;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
font-weight: inherit;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&:focus,
|
|
||||||
&:active,
|
|
||||||
&:hover {
|
|
||||||
&:before {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
display: none;
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
width: 3px;
|
|
||||||
height: 100%;
|
|
||||||
background-color: $darkGreen;
|
|
||||||
left: -16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: $grey;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
.communitysupport {
|
|
||||||
@neat-row;
|
|
||||||
background-color: white;
|
|
||||||
padding: $large 0 $large 0;
|
|
||||||
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
padding: $xl 0 $large 0;
|
|
||||||
h2 {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: $large;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.community {
|
|
||||||
@neat-span-columns 12;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 8;
|
|
||||||
}
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
@neat-span-columns 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.community-features {
|
|
||||||
.feature {
|
|
||||||
margin-top: $medium;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.contributors {
|
|
||||||
@neat-span-columns 12;
|
|
||||||
margin-top: $medium;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 10;
|
|
||||||
}
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
@neat-span-columns 5;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contributor-list {
|
|
||||||
margin-top: 4px;
|
|
||||||
img {
|
|
||||||
width: 32px;
|
|
||||||
margin: 0 4px 4px 0;
|
|
||||||
border-radius: 16px;
|
|
||||||
transition: 0.1s;
|
|
||||||
}
|
|
||||||
img:hover {
|
|
||||||
transform: scale(1.3);
|
|
||||||
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.25), 0 4px 12px 0 rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
.cta {
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
position: relative;
|
|
||||||
top: -65px;
|
|
||||||
width: 880px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cta-primary {
|
|
||||||
background-color: white;
|
|
||||||
padding: $medium $small $medium $small;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
padding: $medium;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
padding: $small $medium $small $medium;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
box-shadow: 0 10px 30px 0 rgba(28, 30, 30, 0.1), 0 3px 9px 0 rgba(28, 30, 30, 0.15);
|
|
||||||
border-radius: $largeBorderRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 25px;
|
|
||||||
color: $lightishGrey;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
.hook {
|
|
||||||
font-weight: $bold;
|
|
||||||
color: $darkGrey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: white;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: $tiny;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
background-color: $blue;
|
|
||||||
background-image: linear-gradient(-180deg, #4a7fdd 0%, #3a69c7 100%);
|
|
||||||
box-shadow: 0 4px 12px 0 rgba(68, 74, 87, 0.1), 0 1px 3px 0 rgba(68, 74, 87, 0.2);
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
padding: 12px 18px 12px 18px;
|
|
||||||
transition: 0.2s;
|
|
||||||
display: inline-block;
|
|
||||||
margin-top: $tiny;
|
|
||||||
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin: 0 0 0 $small;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
box-shadow: 0 4px 12px 0 rgba(68, 74, 87, 0.2), 0 1px 3px 0 rgba(68, 74, 87, 0.4);
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,254 +0,0 @@
|
|||||||
.docs.page,
|
|
||||||
.blog.page {
|
|
||||||
padding: 69px $tiny $xl;
|
|
||||||
text-align: left;
|
|
||||||
@media screen and (min-width: $mobile) {
|
|
||||||
padding: 157px $medium $xl;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 6 24;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.docs-nav {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link,
|
|
||||||
.subnav-link {
|
|
||||||
display: block;
|
|
||||||
font-weight: $regular;
|
|
||||||
font-size: $tiny;
|
|
||||||
color: $grey;
|
|
||||||
line-height: 1.3;
|
|
||||||
margin: 10px 0;
|
|
||||||
text-decoration: none;
|
|
||||||
text-transform: capitalize;
|
|
||||||
transition: color 0.2s ease;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: $darkGreen;
|
|
||||||
font-weight: $bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $darkGreen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.docs-nav-section {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.docs-nav-section-list {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.docs-nav-section-title {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-subsections {
|
|
||||||
margin: $tiny 0;
|
|
||||||
padding: 0 0 0 $tiny;
|
|
||||||
border-left: 2px solid $lightestGrey;
|
|
||||||
list-style-type: none;
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subnav-link {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h1,
|
|
||||||
h2 {
|
|
||||||
font-size: 36px;
|
|
||||||
line-height: 1.4em;
|
|
||||||
|
|
||||||
&.intro-headline {
|
|
||||||
padding: 0 $small;
|
|
||||||
margin-bottom: 86px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: $small;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
color: $grey;
|
|
||||||
font-size: 20px;
|
|
||||||
margin-top: $medium;
|
|
||||||
margin-bottom: $small;
|
|
||||||
|
|
||||||
&.inverse {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta-info {
|
|
||||||
font-size: $tiny;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
text-align: left;
|
|
||||||
margin: 34px 0 $medium 0;
|
|
||||||
|
|
||||||
th,
|
|
||||||
td {
|
|
||||||
padding: $micro;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: $bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody tr {
|
|
||||||
&:nth-child(odd) {
|
|
||||||
background: #fdfdfd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.docs-content,
|
|
||||||
.blog-content {
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 28px;
|
|
||||||
|
|
||||||
.edit-this-page {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pencil {
|
|
||||||
fill: #7ca511;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 17 24;
|
|
||||||
@neat-shift 1 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2:not(:first-child) {
|
|
||||||
margin-top: $medium;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
line-height: 1.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: $darkGreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
background: #f7f7f7;
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
margin: 30px -16px !important;
|
|
||||||
@media (min-width: $xlarge) {
|
|
||||||
margin-right: -120px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
figure {
|
|
||||||
margin-left: 0;
|
|
||||||
|
|
||||||
.gatsby-highlight {
|
|
||||||
margin-top: -20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
figcaption {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
:not(pre) > code {
|
|
||||||
color: inherit;
|
|
||||||
background: $lightestGrey;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 2px 6px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-content h1 {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blog-list-item h2 {
|
|
||||||
margin: 48px 0 0;
|
|
||||||
line-height: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-docs-nav {
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
margin-bottom: $small;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-docs-nav-btn {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-docs-nav-content {
|
|
||||||
/* border: 1px solid $lightishGrey; */
|
|
||||||
background-color: $lighterGrey;
|
|
||||||
padding: $tiny;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-docs-nav-list {
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
.mobile-docs-nav-list {
|
|
||||||
margin-left: $small;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-docs-nav-item {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-docs-nav-link {
|
|
||||||
font-size: 16px;
|
|
||||||
display: block;
|
|
||||||
padding: $micro;
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
.editors {
|
|
||||||
@neat-row;
|
|
||||||
margin: $large 0 $large 0;
|
|
||||||
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
text-align: center;
|
|
||||||
margin: $xxl 0 $xxl 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2,
|
|
||||||
p {
|
|
||||||
max-width: $desktop;
|
|
||||||
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p#editor-intro {
|
|
||||||
max-width: 710px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editors-features {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-top: calc($large * 2);
|
|
||||||
|
|
||||||
@media screen and (max-width: $desktop) {
|
|
||||||
justify-content: flex-start;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-top: $small;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature {
|
|
||||||
min-width: 260px;
|
|
||||||
width: 320px;
|
|
||||||
text-align: left;
|
|
||||||
margin-right: $medium;
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 300px;
|
|
||||||
margin-bottom: $tiny;
|
|
||||||
margin-left: -9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: $desktop) {
|
|
||||||
margin-top: $large;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
footer {
|
|
||||||
background: white;
|
|
||||||
padding: $medium 0 $large 0;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.footer-info {
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
float: left;
|
|
||||||
margin-right: $small;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
color: $grey;
|
|
||||||
font-family: $roboto;
|
|
||||||
font-size: 12px;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: $grey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-buttons {
|
|
||||||
margin-bottom: $small;
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
float: left;
|
|
||||||
margin-right: $small;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
padding: $micro $tiny $micro $tiny;
|
|
||||||
margin-right: $micro;
|
|
||||||
background-color: $lightishGrey;
|
|
||||||
color: white;
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
background-color: $darkGreen;
|
|
||||||
}
|
|
||||||
a:active {
|
|
||||||
background-color: $darkerGreen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,237 +0,0 @@
|
|||||||
.notification {
|
|
||||||
background-color: $darkerGrey;
|
|
||||||
box-sizing: border-box;
|
|
||||||
color: white;
|
|
||||||
display: block;
|
|
||||||
padding: $tiny $small;
|
|
||||||
position: absolute;
|
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 100;
|
|
||||||
|
|
||||||
@media screen and (min-width: $mobile) {
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
em {
|
|
||||||
font-style: normal;
|
|
||||||
color: #8b8b8b;
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup,
|
|
||||||
sub {
|
|
||||||
font-size: initial;
|
|
||||||
vertical-align: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-link {
|
|
||||||
text-decoration: underline;
|
|
||||||
color: $green;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.notification-loud {
|
|
||||||
background-color: $green;
|
|
||||||
color: $darkerGrey;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ header {
|
|
||||||
margin-top: 100px;
|
|
||||||
|
|
||||||
@media screen and (min-width: 360px) {
|
|
||||||
margin-top: 74px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 712px) {
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ div:before,
|
|
||||||
+ .hero:before {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
height: 100px;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
@media screen and (min-width: 360px) {
|
|
||||||
height: 74px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 712px) {
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
background: transparent;
|
|
||||||
box-shadow: none;
|
|
||||||
font-family: $roboto;
|
|
||||||
position: absolute;
|
|
||||||
padding: $medium 0;
|
|
||||||
text-align: center;
|
|
||||||
transition: background 0.2s ease, padding 0.2s ease, box-shadow 0.2s ease;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 100;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
text-align: right;
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.scrolled {
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
background: $darkerGrey;
|
|
||||||
padding: $small 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.docs,
|
|
||||||
&.blog {
|
|
||||||
background: $darkerGrey;
|
|
||||||
padding: $small 0;
|
|
||||||
|
|
||||||
@media screen and (max-width: $tablet) {
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-container {
|
|
||||||
padding-top: $micro;
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: white;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
-webkit-vertical-align: middle !important;
|
|
||||||
margin-left: $tiny;
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
color: $green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-button {
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: $small;
|
|
||||||
vertical-align: middle;
|
|
||||||
position: relative;
|
|
||||||
top: 2px;
|
|
||||||
@media screen and (max-width: $mobile) {
|
|
||||||
margin-top: $tiny;
|
|
||||||
top: 0;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-search {
|
|
||||||
margin-top: 1px;
|
|
||||||
-webkit-margin-top: 0;
|
|
||||||
-webkit-display: inline-block;
|
|
||||||
vertical-align: baseline !important;
|
|
||||||
}
|
|
||||||
input.closed {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
padding: -5px 0 0 0;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
appearance: none;
|
|
||||||
background: none;
|
|
||||||
color: $lightGrey;
|
|
||||||
display: inline-block;
|
|
||||||
font-size: $tiny;
|
|
||||||
font-weight: $regular;
|
|
||||||
max-width: 160px;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
visibility: visible;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
~ .bar {
|
|
||||||
&::before,
|
|
||||||
&::after {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~ .button-submit {
|
|
||||||
margin-top: -35px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.utility-input {
|
|
||||||
display: none;
|
|
||||||
padding: $micro;
|
|
||||||
position: relative;
|
|
||||||
top: -4px;
|
|
||||||
width: auto;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
|
||||||
color: white;
|
|
||||||
margin: 0 0 0 $tiny;
|
|
||||||
padding-top: -5px;
|
|
||||||
padding-bottom: 9px;
|
|
||||||
text-align: left;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 24px;
|
|
||||||
transition: all 0.2s ease-in-out;
|
|
||||||
|
|
||||||
@media screen and (min-width: 1024px) {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus,
|
|
||||||
&:active {
|
|
||||||
outline-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-input-placeholder,
|
|
||||||
&:-moz-placeholder,
|
|
||||||
&::-moz-placeholder,
|
|
||||||
&:-ms-input-placeholder {
|
|
||||||
font-size: $tiny;
|
|
||||||
font-weight: $semibold;
|
|
||||||
text-align: left;
|
|
||||||
text-decoration: none;
|
|
||||||
line-height: $small;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-container {
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
margin-top: 10px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto $tiny auto;
|
|
||||||
width: 100%;
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
margin: -14px 20px -6px 0;
|
|
||||||
width: initial;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,257 +0,0 @@
|
|||||||
.hero {
|
|
||||||
@neat-row;
|
|
||||||
background: $darkerGrey;
|
|
||||||
background-image: linear-gradient(-180deg, #2a2c24 0%, $darkerGrey 20%);
|
|
||||||
color: $blueGrey;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: calc($xl * 2.25) 0 0 0;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
@media screen and (min-width: $mobile) {
|
|
||||||
padding-top: calc($xl * 1.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
padding-top: calc($xl * 1.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.landing {
|
|
||||||
padding-bottom: 100px;
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
padding-bottom: 200px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-copy {
|
|
||||||
margin: $medium auto $xl auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subhead {
|
|
||||||
display: inline-block;
|
|
||||||
margin: $micro auto;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 26px;
|
|
||||||
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strong {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: $green;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cta-header {
|
|
||||||
display: block;
|
|
||||||
margin-top: $small;
|
|
||||||
}
|
|
||||||
.cta-header a {
|
|
||||||
display: inline-block;
|
|
||||||
color: white;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: $tiny;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
background-color: $blue;
|
|
||||||
background-image: linear-gradient(-180deg, #4a7fdd 0%, #3a69c7 100%);
|
|
||||||
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.3), 0 1px 3px 0 rgba(0, 0, 0, 0.6);
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
padding: 10px 14px 8px 14px;
|
|
||||||
transition: 0.2s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.5), 0 1px 3px 0 rgba(0, 0, 0, 1);
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-features {
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature {
|
|
||||||
margin: 0 0 $medium 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-graphic {
|
|
||||||
@neat-span-columns 12;
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 6;
|
|
||||||
float: right;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
img,
|
|
||||||
iframe {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: $largeBorderRadius;
|
|
||||||
box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.15), 0 3px 9px 0 rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-videolink {
|
|
||||||
position: absolute;
|
|
||||||
margin: auto;
|
|
||||||
padding: 10px 0 0 10px;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 90px;
|
|
||||||
height: 90px;
|
|
||||||
color: $blue;
|
|
||||||
background-color: rgba(255, 255, 255, 0.85);
|
|
||||||
box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.05), 0 1px 3px 0 rgba(0, 0, 0, 0.15);
|
|
||||||
border-radius: 100px;
|
|
||||||
transition: 0.1s;
|
|
||||||
}
|
|
||||||
.hero-videolink-arrow {
|
|
||||||
position: absolute;
|
|
||||||
left: 33px;
|
|
||||||
top: 28px;
|
|
||||||
width: 44px;
|
|
||||||
height: 44px;
|
|
||||||
fill: #3a69c7;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.hero-videolink {
|
|
||||||
background-color: $blue;
|
|
||||||
box-shadow: 0 6px 18px 0 rgba(0, 0, 0, 0.15), 0 2px 6px 0 rgba(0, 0, 0, 0.3);
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
.hero-videolink-arrow {
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
.hero-videolink {
|
|
||||||
transform: scale(0.9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*COMMUNITY PAGE*/
|
|
||||||
|
|
||||||
&.community {
|
|
||||||
.hero-copy {
|
|
||||||
text-align: left;
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctas {
|
|
||||||
margin-bottom: $small;
|
|
||||||
|
|
||||||
@media screen and (min-width: $mobile) {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: $green;
|
|
||||||
font-weight: $semibold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.calendar-cta {
|
|
||||||
text-align: center;
|
|
||||||
background: $darkerGrey;
|
|
||||||
background-image: linear-gradient(-17deg, $darkerGrey 17%, $darkGrey 94%);
|
|
||||||
border-radius: $largeBorderRadius;
|
|
||||||
box-shadow: 0 $micro $small rgba(0, 0, 0, 0.1);
|
|
||||||
padding: $medium;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
max-width: 446px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 5;
|
|
||||||
@neat-shift 1;
|
|
||||||
display: inline-block;
|
|
||||||
position: fixed;
|
|
||||||
right: $medium;
|
|
||||||
max-height: calc(100vh - ($xl * 1.5) - $medium);
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1280px) {
|
|
||||||
right: initial;
|
|
||||||
left: calc(50% - $large);
|
|
||||||
}
|
|
||||||
|
|
||||||
.calendar {
|
|
||||||
border-radius: $largeBorderRadius;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 $micro $small rgba(0, 0, 0, 0.5);
|
|
||||||
margin: $small auto;
|
|
||||||
max-width: 250px;
|
|
||||||
|
|
||||||
.month {
|
|
||||||
background: $green;
|
|
||||||
color: $grey;
|
|
||||||
font-weight: $black;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 4px;
|
|
||||||
font-size: $tiny;
|
|
||||||
padding: $tiny;
|
|
||||||
}
|
|
||||||
|
|
||||||
.day {
|
|
||||||
font-size: $xl;
|
|
||||||
font-weight: $black;
|
|
||||||
color: white;
|
|
||||||
border: 1px solid $grey;
|
|
||||||
border-top: none;
|
|
||||||
border-bottom-left-radius: $largeBorderRadius;
|
|
||||||
border-bottom-right-radius: $largeBorderRadius;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strong {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2:not(:first-child) {
|
|
||||||
font-weight: $light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cal-cta {
|
|
||||||
margin-top: $micro;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: $green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,258 +0,0 @@
|
|||||||
@keyframes fadeInUp {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(10px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.centered-text {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
@neat-outer-container;
|
|
||||||
}
|
|
||||||
|
|
||||||
.half,
|
|
||||||
.third,
|
|
||||||
.quarter {
|
|
||||||
padding-bottom: $small;
|
|
||||||
@neat-span-columns 12;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 6;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(even) {
|
|
||||||
@media screen and (min-width: $mobile) and (max-width: 767px) {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.third {
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.quarter {
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.clearfix {
|
|
||||||
&:after {
|
|
||||||
content: ' ';
|
|
||||||
width: 100%;
|
|
||||||
display: table;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-label {
|
|
||||||
color: $grey;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: $semibold;
|
|
||||||
letter-spacing: 1.5px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
background: $darkGreen;
|
|
||||||
content: ' ';
|
|
||||||
display: block;
|
|
||||||
height: 2px;
|
|
||||||
margin-top: 5px;
|
|
||||||
width: $small;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.inverse {
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
&.mono:after {
|
|
||||||
background: $grey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.extended {
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 1.15;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
position: relative;
|
|
||||||
height: 1px;
|
|
||||||
left: -10000%;
|
|
||||||
width: calc(10100%);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img.responsive {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-bg-hero {
|
|
||||||
color: white;
|
|
||||||
background-size: 100% auto;
|
|
||||||
background-size: cover !important;
|
|
||||||
|
|
||||||
h1,
|
|
||||||
h2 {
|
|
||||||
color: white;
|
|
||||||
font-weight: $light;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
font-weight: $thin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination {
|
|
||||||
text-align: center;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
@neat-span-columns 8;
|
|
||||||
@neat-shift 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
display: inline;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active a,
|
|
||||||
a[aria-label] {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: $light;
|
|
||||||
color: $grey;
|
|
||||||
width: 18px;
|
|
||||||
font-size: $tiny;
|
|
||||||
padding: $micro;
|
|
||||||
border-radius: 99px;
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.active a {
|
|
||||||
color: white;
|
|
||||||
background: $green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.disabled a {
|
|
||||||
color: $lighterGrey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.unordered-list ul {
|
|
||||||
margin: 0 0 $small 0;
|
|
||||||
padding: 0;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 28px;
|
|
||||||
list-style-type: none;
|
|
||||||
list-style-position: inside;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
li span {
|
|
||||||
position: relative;
|
|
||||||
padding-left: $small;
|
|
||||||
display: list-item;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: '\2192';
|
|
||||||
color: $green;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.numbered-list ol {
|
|
||||||
list-style-type: decimal-leading-zero;
|
|
||||||
margin: 32px 0 0 0;
|
|
||||||
padding: 0 0 0 78px;
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-bottom: 33px;
|
|
||||||
font-size: 34px;
|
|
||||||
font-weight: $bold;
|
|
||||||
color: $grey;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&:before,
|
|
||||||
&:after {
|
|
||||||
position: absolute;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: 'N';
|
|
||||||
top: 6px;
|
|
||||||
left: -78px;
|
|
||||||
padding-bottom: 2px;
|
|
||||||
border-bottom: 1px solid $green;
|
|
||||||
padding-right: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: 'ọ';
|
|
||||||
left: -69px;
|
|
||||||
top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 34px;
|
|
||||||
margin-bottom: $tiny;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
background: white;
|
|
||||||
left: -19px;
|
|
||||||
height: 10px;
|
|
||||||
width: 10px;
|
|
||||||
top: $small;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: $regular;
|
|
||||||
line-height: 28px;
|
|
||||||
color: $lightGrey;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
.whatsnew {
|
|
||||||
padding: $medium 0 $medium 0;
|
|
||||||
background-color: $lightishGrey;
|
|
||||||
color: white;
|
|
||||||
@media screen and (min-width: $desktop) {
|
|
||||||
margin-top: -98px;
|
|
||||||
padding-top: 75px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
list-style: none;
|
|
||||||
padding-left: 0;
|
|
||||||
@media screen and (max-width: $desktop) {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: white;
|
|
||||||
font-weight: $regular;
|
|
||||||
min-width: 250px;
|
|
||||||
max-width: 320px;
|
|
||||||
margin-right: $medium;
|
|
||||||
@media screen and (max-width: $desktop) {
|
|
||||||
max-width: 100%;
|
|
||||||
min-width: 100%;
|
|
||||||
padding: 16px 0 16px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
padding: 16px 24px 16px 24px;
|
|
||||||
margin: -16px calc($medium - 24px) -16px -24px;
|
|
||||||
background-color: $darkGrey;
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
@media screen and (max-width: $desktop) {
|
|
||||||
margin: 0 -24px 0 -24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a:active {
|
|
||||||
background-color: $darkerGrey;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
.update-metadata {
|
|
||||||
font-size: 13px;
|
|
||||||
color: rgba(255, 255, 255, 0.6);
|
|
||||||
display: block;
|
|
||||||
margin-bottom: $micro;
|
|
||||||
.update-version {
|
|
||||||
font-weight: $bold;
|
|
||||||
background-color: $shadeBlue;
|
|
||||||
color: $darkGrey;
|
|
||||||
padding: 0 4px 0 4px;
|
|
||||||
margin-right: 8px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.update-description {
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
.widgets {
|
|
||||||
margin: 2rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widgets__cloud {
|
|
||||||
margin: $micro calc(-$micro / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.widgets__item {
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
background: transparent;
|
|
||||||
color: $darkGrey;
|
|
||||||
border: 2px solid $darkGreen;
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
padding: calc($micro / 2) $micro;
|
|
||||||
margin: calc($micro / 2);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.2s ease, background 0.2s ease;
|
|
||||||
display: inline-block;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widgets__item:hover,
|
|
||||||
.widgets__item_active {
|
|
||||||
background: $darkGreen;
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widgets__container {
|
|
||||||
margin: 1em 0;
|
|
||||||
background: $lightGrey;
|
|
||||||
border-radius: $borderRadius;
|
|
||||||
transition: height 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget {
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget_open {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget_closing {
|
|
||||||
display: block;
|
|
||||||
animation: widgetOpacity 0.15s ease forwards reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget_opening {
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
opacity: 0;
|
|
||||||
animation: widgetOpacity 0.15s 0.05s ease forwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes widgetOpacity {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget pre {
|
|
||||||
margin-right: 0 !important;
|
|
||||||
margin-left: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.widget h3 {
|
|
||||||
margin-top: 0 !important;
|
|
||||||
}
|
|
96
website/src/global-styles.js
Normal file
96
website/src/global-styles.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Global, css } from '@emotion/core';
|
||||||
|
|
||||||
|
import theme from './theme';
|
||||||
|
|
||||||
|
const globalStyles = css`
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
font-family: ${theme.fontFamily};
|
||||||
|
line-height: ${theme.lineHeight[2]};
|
||||||
|
font-size: ${theme.fontsize[3]};
|
||||||
|
background: ${theme.colors.shadeBlue};
|
||||||
|
margin: 0;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
line-height: ${theme.lineHeight[1]};
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: ${theme.colors.darkGreen};
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gitter-open-chat-button {
|
||||||
|
&,
|
||||||
|
&:visited {
|
||||||
|
padding: ${theme.space[3]} ${theme.space[4]};
|
||||||
|
font-family: ${theme.fontFamily};
|
||||||
|
font-size: ${theme.fontsize[3]};
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
line-height: 1;
|
||||||
|
color: ${theme.colors.gray};
|
||||||
|
background-color: ${theme.colors.green};
|
||||||
|
box-shadow: 0 2px 16px 0 rgba(68, 74, 87, 0.15), 0 1px 4px 0 rgba(68, 74, 87, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${theme.colors.lightGreen};
|
||||||
|
box-shadow: 0 2px 16px 0 rgba(68, 74, 87, 0.25), 0 1px 4px 0 rgba(68, 74, 87, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 6px 3px rgba(62, 160, 127, 0.6);
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: ${theme.colors.lightGray};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const GlobalStyles = () => <Global styles={globalStyles} />;
|
||||||
|
|
||||||
|
export default GlobalStyles;
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import ChatButton from './components/chat-button';
|
||||||
|
|
||||||
class HTML extends React.Component {
|
class HTML extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
@ -24,9 +25,7 @@ class HTML extends React.Component {
|
|||||||
{this.props.preBodyComponents}
|
{this.props.preBodyComponents}
|
||||||
<div key={'body'} id="___gatsby" dangerouslySetInnerHTML={{ __html: this.props.body }} />
|
<div key={'body'} id="___gatsby" dangerouslySetInnerHTML={{ __html: this.props.body }} />
|
||||||
{this.props.postBodyComponents}
|
{this.props.postBodyComponents}
|
||||||
<a className="chat-button" href="/chat">
|
<ChatButton />
|
||||||
<img src="/img/slack.svg" />
|
|
||||||
</a>
|
|
||||||
<script src="//unpkg.com/docsearch.js@2.4.1/dist/cdn/docsearch.min.js" />
|
<script src="//unpkg.com/docsearch.js@2.4.1/dist/cdn/docsearch.min.js" />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0" y="0" viewBox="0 0 56.966 56.966" xml:space="preserve" width="16" height="12" enable-background="new 0 0 56.966 56.966"><path d="M55.146,51.887L41.588,37.786c3.486-4.144,5.396-9.358,5.396-14.786c0-12.682-10.318-23-23-23s-23,10.318-23,23 s10.318,23,23,23c4.761,0,9.298-1.436,13.177-4.162l13.661,14.208c0.571,0.593,1.339,0.92,2.162,0.92 c0.779,0,1.518-0.297,2.079-0.837C56.255,54.982,56.293,53.08,55.146,51.887z M23.984,6c9.374,0,17,7.626,17,17s-7.626,17-17,17 s-17-7.626-17-17S14.61,6,23.984,6z" fill="#FFF"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0" y="0" viewBox="0 0 56.966 56.966" xml:space="preserve" width="16" height="12" enable-background="new 0 0 56.966 56.966"><path d="M55.146,51.887L41.588,37.786c3.486-4.144,5.396-9.358,5.396-14.786c0-12.682-10.318-23-23-23s-23,10.318-23,23 s10.318,23,23,23c4.761,0,9.298-1.436,13.177-4.162l13.661,14.208c0.571,0.593,1.339,0.92,2.162,0.92 c0.779,0,1.518-0.297,2.079-0.837C56.255,54.982,56.293,53.08,55.146,51.887z M23.984,6c9.374,0,17,7.626,17,17s-7.626,17-17,17 s-17-7.626-17-17S14.61,6,23.984,6z" fill="#fff"/></svg>
|
||||||
|
Before Width: | Height: | Size: 629 B After Width: | Height: | Size: 630 B |
@ -1,34 +1,48 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { Link, graphql } from 'gatsby';
|
import { Link, graphql } from 'gatsby';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
|
import Container from '../components/container';
|
||||||
|
import MetaInfo from '../components/meta-info';
|
||||||
|
import Page from '../components/page';
|
||||||
|
import Lead from '../components/lead';
|
||||||
|
|
||||||
|
import theme from '../theme';
|
||||||
|
|
||||||
const Blog = ({ data }) => (
|
const Blog = ({ data }) => (
|
||||||
<Layout>
|
<Layout>
|
||||||
<div className="blog page">
|
<Helmet>
|
||||||
<Helmet>
|
<title>Blog</title>
|
||||||
<title>Blog</title>
|
<meta name="description" content="Recent news and updates about Netlify CMS." />
|
||||||
<meta name="description" content="Recent news and updates about Netlify CMS." />
|
</Helmet>
|
||||||
</Helmet>
|
<Page>
|
||||||
<div className="container">
|
<Container size="sm">
|
||||||
<h1>Netlify CMS Blog</h1>
|
<h1>Netlify CMS Blog</h1>
|
||||||
{data.allMarkdownRemark.edges.map(({ node }) => (
|
{data.allMarkdownRemark.edges.map(({ node }) => (
|
||||||
<article className="blog-list-item" key={node.id}>
|
<article
|
||||||
<h2>
|
key={node.id}
|
||||||
<Link to={node.fields.slug} className="article">
|
css={css`
|
||||||
{node.frontmatter.title}
|
margin-bottom: ${theme.space[5]};
|
||||||
</Link>
|
`}
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
css={css`
|
||||||
|
margin-bottom: 0;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<Link to={node.fields.slug}>{node.frontmatter.title}</Link>
|
||||||
</h2>
|
</h2>
|
||||||
<p className="meta-info">
|
<MetaInfo>
|
||||||
by {node.frontmatter.author} on {node.frontmatter.date}
|
by {node.frontmatter.author} on {node.frontmatter.date}
|
||||||
</p>
|
</MetaInfo>
|
||||||
<p>{node.frontmatter.description}</p>
|
<Lead>{node.frontmatter.description}</Lead>
|
||||||
</article>
|
</article>
|
||||||
))}
|
))}
|
||||||
{/* TODO: pagination */}
|
{/* TODO: pagination */}
|
||||||
</div>
|
</Container>
|
||||||
</div>
|
</Page>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,19 +1,60 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { graphql } from 'gatsby';
|
import { graphql } from 'gatsby';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
import Community from '../components/community';
|
import Markdownify from '../components/markdownify';
|
||||||
|
import PageHero from '../components/page-hero';
|
||||||
|
import HeroTitle from '../components/hero-title';
|
||||||
|
import Lead from '../components/lead';
|
||||||
|
import Container from '../components/container';
|
||||||
|
import SectionLabel from '../components/section-label';
|
||||||
|
import Page from '../components/page';
|
||||||
|
import Grid from '../components/grid';
|
||||||
|
import CommunityChannelsList from '../components/community-channels-list';
|
||||||
|
|
||||||
import '../css/imports/collab.css';
|
import theme from '../theme';
|
||||||
|
|
||||||
const CommunityPage = ({ data }) => {
|
const CommunityPage = ({ data }) => {
|
||||||
const { title, headline, subhead, sections } = data.markdownRemark.frontmatter;
|
const { title, headline, subhead, sections } = data.markdownRemark.frontmatter;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout hasPageHero>
|
||||||
<Helmet title={title} />
|
<Helmet title={title} />
|
||||||
<Community headline={headline} subhead={subhead} sections={sections} />
|
<PageHero>
|
||||||
|
<div
|
||||||
|
css={css`
|
||||||
|
margin-bottom: 20px;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<HeroTitle>
|
||||||
|
<Markdownify source={headline} />
|
||||||
|
</HeroTitle>
|
||||||
|
<Lead light>
|
||||||
|
<Markdownify source={subhead} />
|
||||||
|
</Lead>
|
||||||
|
</div>
|
||||||
|
</PageHero>
|
||||||
|
|
||||||
|
<Container>
|
||||||
|
<Page>
|
||||||
|
<Grid cols={2}>
|
||||||
|
<div
|
||||||
|
css={css`
|
||||||
|
margin-bottom: ${theme.space[5]};
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{sections.map(({ title: sectionTitle, channels }, channelIdx) => (
|
||||||
|
<React.Fragment key={channelIdx}>
|
||||||
|
<SectionLabel>{sectionTitle}</SectionLabel>
|
||||||
|
<CommunityChannelsList channels={channels} />
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
|
</Container>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,30 +1,69 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { graphql } from 'gatsby';
|
import { graphql } from 'gatsby';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
import Markdownify from '../components/markdownify';
|
import Markdownify from '../components/markdownify';
|
||||||
|
import PageHero from '../components/page-hero';
|
||||||
|
import HeroTitle from '../components/hero-title';
|
||||||
import VideoEmbed from '../components/video-embed';
|
import VideoEmbed from '../components/video-embed';
|
||||||
import WhatsNew from '../components/whats-new';
|
import WhatsNew from '../components/whats-new';
|
||||||
import Release from '../components/release';
|
import Lead from '../components/lead';
|
||||||
|
import Features from '../components/features';
|
||||||
|
import HomeSection from '../components/home-section';
|
||||||
|
import Grid from '../components/grid';
|
||||||
|
|
||||||
import '../css/imports/hero.css';
|
import theme from '../theme';
|
||||||
import '../css/imports/cta.css';
|
import { mq } from '../utils';
|
||||||
import '../css/imports/whatsnew.css';
|
|
||||||
import '../css/imports/editors.css';
|
|
||||||
import '../css/imports/community.css';
|
|
||||||
|
|
||||||
const Features = ({ items }) =>
|
const MarkdownButton = styled.span`
|
||||||
items.map(item => (
|
a {
|
||||||
<div className="feature" key={item.feature}>
|
white-space: nowrap;
|
||||||
{item.imgpath && <img src={require(`../img/${item.imgpath}`)} alt="" />}
|
display: inline-block;
|
||||||
<h3>
|
color: white;
|
||||||
<Markdownify source={item.feature} />
|
text-transform: uppercase;
|
||||||
</h3>
|
font-weight: 700;
|
||||||
<p>
|
font-size: ${theme.fontsize[3]};
|
||||||
<Markdownify source={item.description} />
|
letter-spacing: 0.5px;
|
||||||
</p>
|
line-height: ${theme.lineHeight[1]};
|
||||||
</div>
|
background-color: ${theme.colors.blue};
|
||||||
));
|
background-image: linear-gradient(-180deg, #4a7fdd 0%, #3a69c7 100%);
|
||||||
|
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.3), 0 1px 3px 0 rgba(0, 0, 0, 0.6);
|
||||||
|
border-radius: ${theme.radii[1]};
|
||||||
|
padding: ${theme.space[2]} ${theme.space[3]};
|
||||||
|
transition: 0.2s;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.5), 0 1px 3px 0 rgba(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ContribList = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
border-radius: 10rem;
|
||||||
|
margin-right: ${theme.space[1]};
|
||||||
|
margin-bottom: ${theme.space[1]};
|
||||||
|
transition: 0.1s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.3);
|
||||||
|
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.25), 0 4px 12px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const HomePage = ({ data }) => {
|
const HomePage = ({ data }) => {
|
||||||
const landing = data.landing.childDataYaml;
|
const landing = data.landing.childDataYaml;
|
||||||
@ -32,90 +71,115 @@ const HomePage = ({ data }) => {
|
|||||||
const contribs = data.contribs.childDataJson;
|
const contribs = data.contribs.childDataJson;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout hasPageHero>
|
||||||
<div className="landing page">
|
<PageHero>
|
||||||
<section className="landing hero">
|
<div
|
||||||
<div className="contained">
|
css={css`
|
||||||
<div className="hero-copy">
|
margin-bottom: ${theme.space[7]};
|
||||||
<h1 className="headline">
|
`}
|
||||||
<Markdownify source={landing.hero.headline} />
|
>
|
||||||
</h1>
|
<HeroTitle>
|
||||||
<span className="subhead">
|
<Markdownify source={landing.hero.headline} />
|
||||||
<Markdownify source={landing.hero.subhead} />
|
</HeroTitle>
|
||||||
</span>
|
<Lead>
|
||||||
<span className="cta-header">
|
<Markdownify source={landing.hero.subhead} />
|
||||||
<Markdownify source={landing.cta.button} />
|
</Lead>
|
||||||
</span>
|
<Lead>
|
||||||
</div>
|
<MarkdownButton>
|
||||||
<div className="hero-features">
|
<Markdownify source={landing.cta.button} />
|
||||||
<Features items={landing.hero.devfeatures} />
|
</MarkdownButton>
|
||||||
</div>
|
</Lead>
|
||||||
|
</div>
|
||||||
|
<Grid cols={2}>
|
||||||
|
<div>
|
||||||
|
<Features items={landing.hero.devfeatures} kind="light" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
<VideoEmbed />
|
<VideoEmbed />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</Grid>
|
||||||
|
</PageHero>
|
||||||
|
|
||||||
<section className="cta">
|
<section
|
||||||
<div className="cta-primary">
|
css={css`
|
||||||
<p>
|
background: white;
|
||||||
<span className="hook">
|
${mq[2]} {
|
||||||
<Markdownify source={landing.cta.primaryhook} />
|
position: absolute;
|
||||||
</span>{' '}
|
left: 50%;
|
||||||
<Markdownify source={landing.cta.primary} />
|
transform: translate(-50%, -75%);
|
||||||
</p>
|
width: 880px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
css={css`
|
||||||
|
padding: ${theme.space[4]} ${theme.space[5]};
|
||||||
|
color: ${theme.colors.lightishGray};
|
||||||
|
${mq[2]} {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<Lead
|
||||||
|
css={css`
|
||||||
|
margin-right: 2rem;
|
||||||
|
font-size: 18px;
|
||||||
|
${mq[2]} {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<strong>
|
||||||
|
<Markdownify source={landing.cta.primaryhook} />
|
||||||
|
</strong>{' '}
|
||||||
|
<Markdownify source={landing.cta.primary} />
|
||||||
|
</Lead>
|
||||||
|
<MarkdownButton>
|
||||||
<Markdownify source={landing.cta.button} />
|
<Markdownify source={landing.cta.button} />
|
||||||
</div>
|
</MarkdownButton>
|
||||||
</section>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<WhatsNew>
|
<WhatsNew updates={updates.updates} />
|
||||||
{updates.updates.slice(0, 3).map((node, idx) => (
|
|
||||||
<Release
|
|
||||||
key={idx}
|
|
||||||
version={node.version}
|
|
||||||
versionPrevious={updates.updates[idx + 1].version}
|
|
||||||
date={node.date}
|
|
||||||
description={node.description}
|
|
||||||
url={node.url}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</WhatsNew>
|
|
||||||
|
|
||||||
<section className="editors">
|
<HomeSection
|
||||||
<div className="contained">
|
title={<Markdownify source={landing.editors.hook} />}
|
||||||
<h2>
|
text={<Markdownify source={landing.editors.intro} />}
|
||||||
<Markdownify source={landing.editors.hook} />
|
>
|
||||||
</h2>
|
<Grid cols={3}>
|
||||||
<p id="editor-intro">
|
<Features items={landing.editors.features} />
|
||||||
<Markdownify source={landing.editors.intro} />
|
</Grid>
|
||||||
</p>
|
</HomeSection>
|
||||||
<div className="editors-features">
|
|
||||||
<Features items={landing.editors.features} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section className="communitysupport">
|
<HomeSection
|
||||||
<div className="contained">
|
css={css`
|
||||||
<h2>
|
background: white;
|
||||||
<Markdownify source={landing.community.hook} />
|
`}
|
||||||
</h2>
|
title={<Markdownify source={landing.community.hook} />}
|
||||||
<div className="community">
|
>
|
||||||
<div className="community-features">
|
<Grid cols={2}>
|
||||||
<Features items={landing.community.features} />
|
<div>
|
||||||
</div>
|
<Features items={landing.community.features} />
|
||||||
</div>
|
|
||||||
<div className="contributors feature">
|
|
||||||
<h3>{landing.community.contributors}</h3>
|
|
||||||
<div className="contributor-list">
|
|
||||||
{contribs.contributors.map(user => (
|
|
||||||
<a href={user.profile} title={user.name} key={user.login}>
|
|
||||||
<img src={user.avatar_url.replace('v=4', 's=32')} alt={user.login} />
|
|
||||||
</a>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
<div>
|
||||||
</div>
|
<h3
|
||||||
|
css={css`
|
||||||
|
font-size: 18px;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{landing.community.contributors}
|
||||||
|
</h3>
|
||||||
|
<ContribList>
|
||||||
|
{contribs.contributors.map(user => (
|
||||||
|
<a href={user.profile} title={user.name} key={user.login}>
|
||||||
|
<img src={user.avatar_url.replace('v=4', 's=32')} alt={user.login} />
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</ContribList>
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
</HomeSection>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -2,24 +2,31 @@ import React from 'react';
|
|||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { graphql } from 'gatsby';
|
import { graphql } from 'gatsby';
|
||||||
import { trimStart, trimEnd } from 'lodash';
|
import { trimStart, trimEnd } from 'lodash';
|
||||||
|
import { css } from '@emotion/core';
|
||||||
|
|
||||||
import TwitterMeta from '../components/twitter-meta';
|
import TwitterMeta from '../components/twitter-meta';
|
||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
|
import Container from '../components/container';
|
||||||
|
import Markdown from '../components/markdown';
|
||||||
|
import MetaInfo from '../components/meta-info';
|
||||||
|
import Page from '../components/page';
|
||||||
|
|
||||||
export const BlogPostTemplate = ({ title, author, date, body, html }) => (
|
export const BlogPostTemplate = ({ title, author, date, body, html }) => (
|
||||||
<div className="docs page">
|
<Container size="sm">
|
||||||
<div className="container">
|
<Page as="article">
|
||||||
<article className="blog-content" id="blog-content">
|
<h1
|
||||||
<div className="blog-post-header">
|
css={css`
|
||||||
<h1>{title}</h1>
|
margin-bottom: 0;
|
||||||
<p className="meta-info">
|
`}
|
||||||
by {author} on {date}
|
>
|
||||||
</p>
|
{title}
|
||||||
</div>
|
</h1>
|
||||||
{body ? body : <div dangerouslySetInnerHTML={{ __html: html }} />}
|
<MetaInfo>
|
||||||
</article>
|
by {author} on {date}
|
||||||
</div>
|
</MetaInfo>
|
||||||
</div>
|
<Markdown html={body || html} />
|
||||||
|
</Page>
|
||||||
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
const BlogPost = ({ data }) => {
|
const BlogPost = ({ data }) => {
|
||||||
|
@ -7,9 +7,9 @@ import Layout from '../components/layout';
|
|||||||
import EditLink from '../components/edit-link';
|
import EditLink from '../components/edit-link';
|
||||||
import Widgets from '../components/widgets';
|
import Widgets from '../components/widgets';
|
||||||
import DocsNav from '../components/docs-nav';
|
import DocsNav from '../components/docs-nav';
|
||||||
import MobileNav from '../components/mobile-nav';
|
import Container from '../components/container';
|
||||||
|
import SidebarLayout from '../components/sidebar-layout';
|
||||||
import '../css/imports/docs.css';
|
import Markdown from '../components/markdown';
|
||||||
|
|
||||||
const toMenu = (menu, nav) =>
|
const toMenu = (menu, nav) =>
|
||||||
menu.map(group => ({
|
menu.map(group => ({
|
||||||
@ -17,10 +17,9 @@ const toMenu = (menu, nav) =>
|
|||||||
group: nav.group.find(g => g.fieldValue === group.name),
|
group: nav.group.find(g => g.fieldValue === group.name),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const DocsSidebar = ({ docsNav, location, history }) => (
|
const DocsSidebar = ({ docsNav, location }) => (
|
||||||
<aside id="sidebar" className="sidebar">
|
<aside>
|
||||||
<DocsNav items={docsNav} location={location} />
|
<DocsNav items={docsNav} location={location} />
|
||||||
<MobileNav items={docsNav} history={history} />
|
|
||||||
</aside>
|
</aside>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -34,22 +33,22 @@ export const DocsTemplate = ({
|
|||||||
showSidebar,
|
showSidebar,
|
||||||
docsNav,
|
docsNav,
|
||||||
location,
|
location,
|
||||||
history,
|
|
||||||
}) => (
|
}) => (
|
||||||
<div className="docs detail page">
|
<Container size="md">
|
||||||
<div className="container">
|
<SidebarLayout
|
||||||
{showSidebar && <DocsSidebar docsNav={docsNav} location={location} history={history} />}
|
sidebar={<div>{showSidebar && <DocsSidebar docsNav={docsNav} location={location} />}</div>}
|
||||||
<article className="docs-content" id="docs-content">
|
>
|
||||||
|
<article data-docs-content>
|
||||||
{editLinkPath && <EditLink path={editLinkPath} />}
|
{editLinkPath && <EditLink path={editLinkPath} />}
|
||||||
<h1>{title}</h1>
|
<h1>{title}</h1>
|
||||||
{body ? body : <div dangerouslySetInnerHTML={{ __html: html }} />}
|
<Markdown html={body || html} />
|
||||||
{showWidgets && <Widgets widgets={widgets} />}
|
{showWidgets && <Widgets widgets={widgets} />}
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</SidebarLayout>
|
||||||
</div>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
const DocPage = ({ data, location, history }) => {
|
const DocPage = ({ data, location }) => {
|
||||||
const { nav, page, widgets, menu } = data;
|
const { nav, page, widgets, menu } = data;
|
||||||
|
|
||||||
const docsNav = toMenu(menu.siteMetadata.menu.docs, nav);
|
const docsNav = toMenu(menu.siteMetadata.menu.docs, nav);
|
||||||
@ -66,7 +65,6 @@ const DocPage = ({ data, location, history }) => {
|
|||||||
widgets={widgets}
|
widgets={widgets}
|
||||||
docsNav={docsNav}
|
docsNav={docsNav}
|
||||||
location={location}
|
location={location}
|
||||||
history={history}
|
|
||||||
showSidebar
|
showSidebar
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -1,50 +1,37 @@
|
|||||||
// if you change these you must restart the server
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// colors
|
colors: {
|
||||||
lightestGrey: '#E6E6E6',
|
white: '#fff',
|
||||||
lighterGrey: '#F7F8F8',
|
black: '#000',
|
||||||
lightGrey: '#F6F6F6',
|
lightestGray: '#E6E6E6',
|
||||||
lightishGrey: '#51555D',
|
lighterGray: '#F7F8F8',
|
||||||
grey: '#313D3E',
|
lightGray: '#F6F6F6',
|
||||||
darkGrey: '#2F3132',
|
lightishGray: '#51555D',
|
||||||
darkerGrey: '#1E1F21',
|
gray: '#313D3E',
|
||||||
blueGrey: '#BCC2CE',
|
darkGray: '#2F3132',
|
||||||
lightGreen: '#97bf2f',
|
darkerGray: '#1E1F21',
|
||||||
green: '#C9FA4B',
|
blueGray: '#BCC2CE',
|
||||||
darkGreen: '#7CA511',
|
lightGreen: '#97bf2f',
|
||||||
darkerGreen: '#628013',
|
green: '#C9FA4B',
|
||||||
shadeBlue: '#EFF0F4',
|
darkGreen: '#7CA511',
|
||||||
blue: '#3A69C7',
|
darkerGreen: '#628013',
|
||||||
|
shadeBlue: '#EFF0F4',
|
||||||
// typography
|
blue: '#3A69C7',
|
||||||
thin: 100,
|
},
|
||||||
light: 300,
|
fontWeight: {
|
||||||
regular: 400,
|
thin: 100,
|
||||||
semibold: 500,
|
light: 300,
|
||||||
bold: 700,
|
regular: 400,
|
||||||
black: 900,
|
semibold: 500,
|
||||||
|
bold: 700,
|
||||||
// fonts
|
black: 900,
|
||||||
roboto: "'Roboto', -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif",
|
},
|
||||||
|
fontFamily: "'Roboto', -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif",
|
||||||
// padding
|
fontsize: ['10px', '12px', '14px', '16px', '18px', '24px', '32px', '42px', '64px'],
|
||||||
micro: '8px',
|
lineHeight: [1, 1.3, 1.7],
|
||||||
tiny: '16px',
|
space: [0, '4px', '8px', '16px', '24px', '40px', '64px', '104px', '152px'],
|
||||||
small: '24px',
|
radii: [0, '4px', '8px'],
|
||||||
medium: '40px',
|
breakpoints: [480, 768, 960, 1200, 1280],
|
||||||
large: '64px',
|
zIndexes: {
|
||||||
xl: '104px',
|
header: 100,
|
||||||
xxl: '152px',
|
},
|
||||||
|
|
||||||
// border radius
|
|
||||||
borderRadius: '4px',
|
|
||||||
largeBorderRadius: '8px',
|
|
||||||
|
|
||||||
// responsive breakpoints
|
|
||||||
mobile: '480px',
|
|
||||||
tablet: '768px',
|
|
||||||
desktop: '960px',
|
|
||||||
display: '1200px',
|
|
||||||
xlarge: '1280px',
|
|
||||||
};
|
};
|
||||||
|
5
website/src/utils.js
Normal file
5
website/src/utils.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import theme from './theme';
|
||||||
|
|
||||||
|
export const mq = theme.breakpoints.map(bp => `@media (min-width: ${bp}px)`);
|
||||||
|
|
||||||
|
export const themeGet = (key, initial) => props => props.theme[key] || initial;
|
10114
website/yarn.lock
10114
website/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user