package updates

* update most dependencies
* simplify linting: kick out editorconfig, stylelint
* update to @oceanprotocol/art v3.0.0, source new assets and update UI for it
This commit is contained in:
Matthias Kretschmann 2020-07-01 11:24:21 +02:00
parent 40e160c4c7
commit 7014ee27a7
Signed by: m
GPG Key ID: 606EEEF3C479A91F
75 changed files with 28366 additions and 3525 deletions

View File

@ -1,12 +0,0 @@
root = true
[*]
charset = utf-8
indent_size = 4
end_of_line = lf
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{json,yml,yaml,md}]
indent_size = 2

1
.gitignore vendored
View File

@ -1,5 +1,4 @@
node_modules node_modules
package-lock.json
yarn.lock yarn.lock
yarn-error.log yarn-error.log
.cache .cache

View File

@ -1,5 +1,6 @@
{ {
"semi": false, "semi": false,
"singleQuote": true, "singleQuote": true,
"trailingComma": "none" "trailingComma": "none",
"tabWidth": 2
} }

View File

@ -1,11 +0,0 @@
{
"extends": [
"stylelint-config-bigchaindb",
"stylelint-config-css-modules",
"./node_modules/prettier-stylelint/config.js"
],
"syntax": "scss",
"rules": {
"no-descending-specificity": null
}
}

View File

@ -75,7 +75,6 @@ To enforce a consistent code style, linting is setup for pretty much every file.
In this repo the following tools are setup for that: In this repo the following tools are setup for that:
- ESLint with [eslint-config-oceanprotocol](https://github.com/oceanprotocol/eslint-config-oceanprotocol) - ESLint with [eslint-config-oceanprotocol](https://github.com/oceanprotocol/eslint-config-oceanprotocol)
- Stylelint with [stylelint-config-bigchaindb](https://github.com/bigchaindb/stylelint-config-bigchaindb)
- [markdownlint](https://github.com/DavidAnson/markdownlint) - [markdownlint](https://github.com/DavidAnson/markdownlint)
- [Prettier](https://prettier.io) - [Prettier](https://prettier.io)
@ -93,7 +92,6 @@ If you use VS Code as your editor, you can install those extensions to get linti
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
- [stylelint](https://marketplace.visualstudio.com/items?itemName=shinnn.stylelint)
- [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) - [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
## Deployment ## Deployment
@ -125,7 +123,7 @@ Requires authorization against AWS with [one of the various ways](https://docs.a
## License ## License
```text ```text
Copyright 2019 Ocean Protocol Foundation Ltd. Copyright 2020 Ocean Protocol Foundation Ltd.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

108
config.js
View File

@ -1,57 +1,57 @@
module.exports = { module.exports = {
siteTitle: 'Ocean Protocol Documentation', siteTitle: 'Ocean Protocol Documentation',
siteShortTitle: 'Docs', siteShortTitle: 'Docs',
siteDescription: siteDescription:
'Learn about the components of the Ocean Protocol software stack, and how to run or use the components relevant to you.', 'Learn about the components of the Ocean Protocol software stack, and how to run or use the components relevant to you.',
siteUrl: process.env.SITE_URL || 'https://docs.oceanprotocol.com', siteUrl: process.env.SITE_URL || 'https://docs.oceanprotocol.com',
siteIcon: 'node_modules/@oceanprotocol/art/logo/favicon-black.png', siteIcon: 'node_modules/@oceanprotocol/art/logo/favicon-black.png',
siteCompany: 'Ocean Protocol Foundation Ltd.', siteCompany: 'Ocean Protocol Foundation Ltd.',
analyticsId: 'UA-60614729-11', analyticsId: 'UA-60614729-11',
social: { social: {
Site: 'https://oceanprotocol.com', Site: 'https://oceanprotocol.com',
Blog: 'https://blog.oceanprotocol.com', Blog: 'https://blog.oceanprotocol.com',
GitHub: 'https://github.com/oceanprotocol', GitHub: 'https://github.com/oceanprotocol',
Twitter: 'https://twitter.com/oceanprotocol', Twitter: 'https://twitter.com/oceanprotocol',
Discord: 'https://discord.gg/TnXjkR5', Discord: 'https://discord.gg/TnXjkR5',
Port: 'https://port.oceanprotocol.com', Port: 'https://port.oceanprotocol.com',
Telegram: 'https://t.me/OceanProtocol_Community' Telegram: 'https://t.me/OceanProtocol_Community'
},
githubContentPath:
'https://github.com/oceanprotocol/docs/blob/master/content',
githubDevOceanPath:
'https://github.com/oceanprotocol/dev-ocean/blob/master/doc',
redirects: [
{
from: '/concepts/',
to: '/concepts/introduction/'
}, },
githubContentPath: {
'https://github.com/oceanprotocol/docs/blob/master/content', from: '/setup/',
githubDevOceanPath: to: '/setup/quickstart/'
'https://github.com/oceanprotocol/dev-ocean/blob/master/doc', },
redirects: [ {
{ from: '/tutorials/',
from: '/concepts/', to: '/tutorials/introduction/'
to: '/concepts/introduction/' },
}, {
{ from: '/references/',
from: '/setup/', to: '/references/introduction/'
to: '/setup/quickstart/' },
}, {
{ from: '/tutorials/wallets/',
from: '/tutorials/', to: '/concepts/wallets/'
to: '/tutorials/introduction/' },
}, {
{ from: '/concepts/production-network/',
from: '/references/', to: '/concepts/pacific-network/'
to: '/references/introduction/' },
}, {
{ from: '/references/squid-py/',
from: '/tutorials/wallets/', to: 'https://squid-py.readthedocs.io/en/latest/'
to: '/concepts/wallets/' },
}, {
{ from: '/references/squid-java/',
from: '/concepts/production-network/', to: 'https://www.javadoc.io/doc/com.oceanprotocol/squid/'
to: '/concepts/pacific-network/' }
}, ]
{
from: '/references/squid-py/',
to: 'https://squid-py.readthedocs.io/en/latest/'
},
{
from: '/references/squid-java/',
to: 'https://www.javadoc.io/doc/com.oceanprotocol/squid/'
}
]
} }

View File

@ -3,10 +3,8 @@ title: Set Up a Compute-to-Data Environment
description: Set Up a Compute-to-Data environment. description: Set Up a Compute-to-Data environment.
--- ---
## Requirements ## Requirements
First, create a folder with the following structure: First, create a folder with the following structure:
```text ```text
@ -22,23 +20,22 @@ Then you need the following parts:
- a working Kubernetes (K8s) cluster (Minikube is a good start) - a working Kubernetes (K8s) cluster (Minikube is a good start)
- a working `kubectl` connected to the K8s cluster - a working `kubectl` connected to the K8s cluster
- one folder (/ocean/operator-service/), in which we will download the following: - one folder (/ocean/operator-service/), in which we will download the following:
- [postgres-configmap.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/postgres-configmap.yaml) - [postgres-configmap.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/postgres-configmap.yaml)
- [postgres-storage.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/postgres-storage.yaml) - [postgres-storage.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/postgres-storage.yaml)
- [postgres-deployment.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/postgres-deployment.yaml) - [postgres-deployment.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/postgres-deployment.yaml)
- [postgres-service.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/postgresql-service.yaml) - [postgres-service.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/postgresql-service.yaml)
- [deployment.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/deployment.yaml) - [deployment.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/deployment.yaml)
- [role_binding.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/role_binding.yaml) - [role_binding.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/role_binding.yaml)
- [service_account.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/service_account.yaml) - [service_account.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-service/develop/deploy_on_k8s/service_account.yaml)
- one folder (/ocean/operator-engine/), in which we will download the following: - one folder (/ocean/operator-engine/), in which we will download the following:
- [sa.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/sa.yml) - [sa.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/sa.yml)
- [binding.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/binding.yml) - [binding.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/binding.yml)
- [operator.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/operator.yml) - [operator.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/operator.yml)
- [computejob-crd.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/computejob-crd.yaml) - [computejob-crd.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/computejob-crd.yaml)
- [workflow-crd.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/workflow-crd.yaml) - [workflow-crd.yaml](https://raw.githubusercontent.com/oceanprotocol/operator-engine/develop/k8s_install/workflow-crd.yaml)
## Customize your Operator Service deployment ## Customize your Operator Service deployment
The following resources need attention: The following resources need attention:
| Resource | Variable | Description | | Resource | Variable | Description |
@ -66,7 +63,6 @@ For AWS , please make sure that your class allocates volumes in the same region
We created our own 'standard' class in AWS: We created our own 'standard' class in AWS:
```bash ```bash
kubectl get storageclass standard -o yaml kubectl get storageclass standard -o yaml
``` ```
@ -93,7 +89,7 @@ Or we can use this for minikube:
apiVersion: storage.k8s.io/v1 apiVersion: storage.k8s.io/v1
kind: StorageClass kind: StorageClass
metadata: metadata:
name: standard name: standard
provisioner: docker.io/hostpath provisioner: docker.io/hostpath
reclaimPolicy: Retain reclaimPolicy: Retain
``` ```
@ -107,7 +103,6 @@ kubectl create ns ocean-operator
kubectl create ns ocean-compute kubectl create ns ocean-compute
``` ```
## Deploy Operator Service ## Deploy Operator Service
```bash ```bash
@ -121,7 +116,6 @@ kubectl apply -f /ocean/operator-service/role_binding.yaml
kubectl apply -f /ocean/operator-service/service_account.yaml kubectl apply -f /ocean/operator-service/service_account.yaml
``` ```
## Deploy Operator Engine ## Deploy Operator Engine
```bash ```bash
@ -134,14 +128,12 @@ kubectl apply -f /ocean/operator-engine/workflow-crd.yaml
kubectl create -f /ocean/operator-service/postgres-configmap.yaml kubectl create -f /ocean/operator-service/postgres-configmap.yaml
``` ```
## Expose Operator Service ## Expose Operator Service
```bash ```bash
kubectl expose deployment operator-api --namespace=ocean-operator --port=8050 kubectl expose deployment operator-api --namespace=ocean-operator --port=8050
``` ```
Run a port forward or create your ingress service (not covered here): Run a port forward or create your ingress service (not covered here):
```bash ```bash
@ -156,10 +148,9 @@ If your cluster is running on example.com:
curl -X POST "http://example.com:8050/api/v1/operator/pgsqlinit" -H "accept: application/json" curl -X POST "http://example.com:8050/api/v1/operator/pgsqlinit" -H "accept: application/json"
``` ```
## Update Brizo ## Update Brizo
Update Brizo by adding or updating the `OPERATOR_SERVICE_URL` env in `/ocean/barge/compose-files/brizo.yaml` Update Brizo by adding or updating the `OPERATOR_SERVICE_URL` env in `/ocean/barge/compose-files/brizo.yaml`
```yaml ```yaml
OPERATOR_SERVICE_URL: http://example.com:8050/ OPERATOR_SERVICE_URL: http://example.com:8050/

2
external/dev-ocean vendored

@ -1 +1 @@
Subproject commit 90846d10e449159eec5fe762d48e595d5a008135 Subproject commit ba98510529e00ff9411a7df8a8c478dc3b58b635

View File

@ -3,18 +3,18 @@ import './src/styles/global.scss'
// IntersectionObserver polyfill for gatsby-image (Safari, IE) // IntersectionObserver polyfill for gatsby-image (Safari, IE)
if (typeof window.IntersectionObserver === 'undefined') { if (typeof window.IntersectionObserver === 'undefined') {
// eslint-disable-next-line no-unused-expressions // eslint-disable-next-line no-unused-expressions
import('intersection-observer') import('intersection-observer')
} }
// Display a message when a service worker updates // Display a message when a service worker updates
// https://www.gatsbyjs.org/docs/add-offline-support-with-a-service-worker/#displaying-a-message-when-a-service-worker-updates // https://www.gatsbyjs.org/docs/add-offline-support-with-a-service-worker/#displaying-a-message-when-a-service-worker-updates
export const onServiceWorkerUpdateReady = () => { export const onServiceWorkerUpdateReady = () => {
const answer = window.confirm( const answer = window.confirm(
'This application has been updated. ' + 'This application has been updated. ' +
'Reload to display the latest version?' 'Reload to display the latest version?'
) )
if (answer === true) { if (answer === true) {
window.location.reload() window.location.reload()
} }
} }

View File

@ -1,173 +1,170 @@
require('dotenv').config() require('dotenv').config()
if (!process.env.GITHUB_TOKEN) { if (!process.env.GITHUB_TOKEN) {
throw new Error( throw new Error(
`A GitHub token is required to build the site. Check the README `A GitHub token is required to build the site. Check the README
\nhttps://github.com/oceanprotocol/docs.` \nhttps://github.com/oceanprotocol/docs.`
) )
} }
const config = require('./config.js') const config = require('./config.js')
module.exports = { module.exports = {
siteMetadata: { siteMetadata: {
// spread all of our config values here // spread all of our config values here
// so they can easily be queried with GraphQL // so they can easily be queried with GraphQL
...config ...config
},
plugins: [
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'images',
path: `${__dirname}/src/images`
}
}, },
plugins: [ {
{ resolve: 'gatsby-source-filesystem',
resolve: 'gatsby-source-filesystem', options: {
options: { name: 'content',
name: 'images', path: `${__dirname}/content`
path: `${__dirname}/src/images` }
} },
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'data',
path: `${__dirname}/data`
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'art',
path: `${__dirname}/node_modules/@oceanprotocol/art`
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'dev-ocean',
path: `${__dirname}/external/dev-ocean/doc`
}
},
{
resolve: 'gatsby-source-graphql',
options: {
typeName: 'GitHub',
fieldName: 'github',
url: 'https://api.github.com/graphql',
headers: {
Authorization: `bearer ${process.env.GITHUB_TOKEN}`
}, },
{ // Additional options to pass to node-fetch
resolve: 'gatsby-source-filesystem', fetchOptions: {},
refetchInterval: 300 // 5 min.
}
},
{
resolve: 'gatsby-transformer-remark',
options: {
plugins: [
{
resolve: 'gatsby-remark-images',
options: { options: {
name: 'content', maxWidth: 666,
path: `${__dirname}/content` quality: 80,
withWebp: true,
linkImagesToOriginal: false,
showCaptions: true
} }
}, },
{ {
resolve: 'gatsby-source-filesystem', resolve: 'gatsby-remark-github',
options: { options: {
name: 'data', marker: 'GITHUB-EMBED',
path: `${__dirname}/data` insertEllipsisComments: false,
ellipsisPhrase: '...',
useCache: false,
cacheKey: 'gatsby-remark-github-v1',
token: process.env.GITHUB_TOKEN
} }
}, },
{ 'gatsby-remark-smartypants',
resolve: 'gatsby-source-filesystem', 'gatsby-remark-embed-video',
'gatsby-remark-responsive-iframe',
'gatsby-remark-autolink-headers',
'gatsby-remark-code-titles',
{
// https://github.com/andrewbranch/gatsby-remark-vscode
resolve: 'gatsby-remark-vscode',
options: { options: {
name: 'art', theme: 'Quiet Light',
path: `${__dirname}/node_modules/@oceanprotocol/art` injectStyles: false,
languageAliases: {
text: 'log'
}
} }
}, },
{ 'gatsby-remark-copy-linked-files',
resolve: 'gatsby-source-filesystem', {
resolve: 'gatsby-remark-component',
options: { options: {
name: 'dev-ocean', components: ['repo']
path: `${__dirname}/external/dev-ocean/doc`
} }
}, }
{ ]
resolve: 'gatsby-source-graphql', }
options: { },
typeName: 'GitHub', 'gatsby-transformer-yaml',
fieldName: 'github', {
url: 'https://api.github.com/graphql', resolve: 'gatsby-plugin-sass',
headers: { options: {
Authorization: `bearer ${process.env.GITHUB_TOKEN}` includePaths: [`${__dirname}/node_modules`, `${__dirname}/src/styles`]
}, }
// Additional options to pass to node-fetch },
fetchOptions: {}, 'gatsby-transformer-sharp',
refetchInterval: 300 // 5 min. 'gatsby-plugin-sharp',
} {
}, resolve: 'gatsby-plugin-svgr',
{ options: {
resolve: 'gatsby-transformer-remark', icon: true,
options: { viewBox: false
plugins: [ // see https://github.com/smooth-code/svgr for a list of all options
{ }
resolve: 'gatsby-remark-images', },
options: { 'gatsby-plugin-catch-links',
maxWidth: 666, 'gatsby-plugin-react-helmet',
quality: 80, {
withWebp: true, resolve: 'gatsby-plugin-sitemap',
linkImagesToOriginal: false, options: {
showCaptions: true exclude: ['/test', '/references/petstore']
} }
}, },
{ {
resolve: 'gatsby-remark-github', resolve: 'gatsby-plugin-manifest',
options: { options: {
marker: 'GITHUB-EMBED', name: config.siteTitle,
insertEllipsisComments: false, short_name: config.siteShortTitle,
ellipsisPhrase: '...', description: config.siteDescription,
useCache: false, start_url: '/',
cacheKey: 'gatsby-remark-github-v1', background_color: '#e2e2e2',
token: process.env.GITHUB_TOKEN theme_color: '#141414',
} display: 'minimal-ui',
}, icon: config.siteIcon
'gatsby-remark-smartypants', }
'gatsby-remark-embed-video', },
'gatsby-remark-responsive-iframe', 'gatsby-plugin-webpack-size',
'gatsby-remark-autolink-headers', 'gatsby-plugin-offline',
'gatsby-remark-code-titles', {
{ resolve: 'gatsby-plugin-google-analytics',
// https://github.com/andrewbranch/gatsby-remark-vscode options: {
resolve: 'gatsby-remark-vscode', trackingId: config.analyticsId,
options: { head: false,
theme: 'Quiet Light', anonymize: true,
injectStyles: false, respectDNT: true,
languageAliases: { cookieDomain: 'oceanprotocol.com'
text: 'log' }
} }
} ]
},
'gatsby-remark-copy-linked-files',
{
resolve: 'gatsby-remark-component',
options: {
components: ['repo']
}
}
]
}
},
'gatsby-transformer-yaml',
{
resolve: 'gatsby-plugin-sass',
options: {
includePaths: [
`${__dirname}/node_modules`,
`${__dirname}/src/styles`
]
}
},
'gatsby-transformer-sharp',
'gatsby-plugin-sharp',
{
resolve: 'gatsby-plugin-svgr',
options: {
icon: true,
viewBox: false
// see https://github.com/smooth-code/svgr for a list of all options
}
},
'gatsby-plugin-catch-links',
'gatsby-plugin-react-helmet',
{
resolve: 'gatsby-plugin-sitemap',
options: {
exclude: ['/test', '/references/petstore']
}
},
{
resolve: 'gatsby-plugin-manifest',
options: {
name: config.siteTitle,
short_name: config.siteShortTitle,
description: config.siteDescription,
start_url: '/',
background_color: '#e2e2e2',
theme_color: '#141414',
display: 'minimal-ui',
icon: config.siteIcon
}
},
'gatsby-plugin-webpack-size',
'gatsby-plugin-offline',
{
resolve: 'gatsby-plugin-google-analytics',
options: {
trackingId: config.analyticsId,
head: false,
anonymize: true,
respectDNT: true,
cookieDomain: 'oceanprotocol.com'
}
}
]
} }

View File

@ -6,250 +6,237 @@ const Swagger = require('swagger-client')
const { redirects } = require('./config') const { redirects } = require('./config')
exports.onCreateNode = ({ node, getNode, actions }) => { exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions const { createNodeField } = actions
if (node.internal.type === 'MarkdownRemark') { if (node.internal.type === 'MarkdownRemark') {
const fileNode = getNode(node.parent) const fileNode = getNode(node.parent)
const parsedFilePath = path.parse(fileNode.relativePath) const parsedFilePath = path.parse(fileNode.relativePath)
let slug = createFilePath({ node, getNode, basePath: 'content' }) let slug = createFilePath({ node, getNode, basePath: 'content' })
let section = parsedFilePath.dir let section = parsedFilePath.dir
if (node.frontmatter.slug) { if (node.frontmatter.slug) {
;({ slug } = node.frontmatter) ;({ slug } = node.frontmatter)
}
if (node.frontmatter.section) {
;({ section } = node.frontmatter)
}
createNodeField({
node,
name: 'slug',
value: slug
})
createNodeField({
node,
name: 'section',
value: section
})
} }
if (node.frontmatter.section) {
;({ section } = node.frontmatter)
}
createNodeField({
node,
name: 'slug',
value: slug
})
createNodeField({
node,
name: 'section',
value: section
})
}
} }
exports.createPages = ({ graphql, actions }) => { exports.createPages = ({ graphql, actions }) => {
const { createPage, createRedirect } = actions const { createPage, createRedirect } = actions
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
resolve( resolve(
graphql( graphql(
` `
query { query {
allMarkdownRemark( allMarkdownRemark(
filter: { fileAbsolutePath: { regex: "/content/" } } filter: { fileAbsolutePath: { regex: "/content/" } }
) { ) {
edges { edges {
node { node {
fields { fields {
slug slug
section section
} }
}
}
}
devOceanDocs: allMarkdownRemark(
filter: {
fileAbsolutePath: { regex: "/dev-ocean/doc/" }
}
) {
edges {
node {
fields {
slug
section
}
frontmatter {
slug
title
description
section
}
}
}
}
squidJs: github {
repository(
name: "squid-js"
owner: "oceanprotocol"
) {
name
releases(
first: 30
orderBy: {
field: CREATED_AT
direction: DESC
}
) {
edges {
node {
isPrerelease
isDraft
releaseAssets(
first: 1
name: "squid-js.json"
) {
edges {
node {
name
downloadUrl
}
}
}
}
}
}
}
}
}
`
).then(async (result) => {
if (result.errors) {
console.log(result.errors)
reject(result.errors)
} }
}
}
const docTemplate = path.resolve('./src/templates/Doc.jsx') devOceanDocs: allMarkdownRemark(
const posts = result.data.allMarkdownRemark.edges filter: { fileAbsolutePath: { regex: "/dev-ocean/doc/" } }
) {
edges {
node {
fields {
slug
section
}
frontmatter {
slug
title
description
section
}
}
}
}
// squidJs: github {
// Create Doc pages repository(name: "squid-js", owner: "oceanprotocol") {
// name
posts.forEach((post) => { releases(
createPage({ first: 30
path: `${post.node.fields.slug}`, orderBy: { field: CREATED_AT, direction: DESC }
component: docTemplate, ) {
context: { edges {
slug: post.node.fields.slug, node {
section: post.node.fields.section isPrerelease
isDraft
releaseAssets(first: 1, name: "squid-js.json") {
edges {
node {
name
downloadUrl
}
} }
}) }
}) }
}
}
}
}
}
`
).then(async (result) => {
if (result.errors) {
console.log(result.errors)
reject(result.errors)
}
// const docTemplate = path.resolve('./src/templates/Doc.jsx')
// Create pages from dev-ocean contents const posts = result.data.allMarkdownRemark.edges
//
const postsDevOcean = result.data.devOceanDocs.edges
postsDevOcean //
// only grab files with required frontmatter defined // Create Doc pages
.filter( //
(post) => posts.forEach((post) => {
post.node.frontmatter && createPage({
post.node.frontmatter.slug && path: `${post.node.fields.slug}`,
post.node.frontmatter.title && component: docTemplate,
post.node.frontmatter.description && context: {
post.node.frontmatter.section slug: post.node.fields.slug,
) section: post.node.fields.section
.forEach((post) => { }
createPage({ })
path: `${post.node.fields.slug}`, })
component: docTemplate,
context: {
slug: post.node.fields.slug,
section: post.node.fields.section
}
})
})
// API: brizo, aquarius //
await createSwaggerPages(createPage) // Create pages from dev-ocean contents
//
const postsDevOcean = result.data.devOceanDocs.edges
// API: squid-js postsDevOcean
const lastRelease = result.data.squidJs.repository.releases.edges.filter( // only grab files with required frontmatter defined
({ node }) => !node.isPrerelease && !node.isDraft .filter(
)[0].node.releaseAssets.edges[0].node (post) =>
await createTypeDocPage( post.node.frontmatter &&
createPage, post.node.frontmatter.slug &&
result.data.squidJs.repository.name, post.node.frontmatter.title &&
lastRelease.downloadUrl post.node.frontmatter.description &&
) post.node.frontmatter.section
)
// .forEach((post) => {
// create redirects createPage({
// path: `${post.node.fields.slug}`,
redirects.forEach(({ from, to }) => { component: docTemplate,
createRedirect({ context: {
fromPath: from, slug: post.node.fields.slug,
redirectInBrowser: true, section: post.node.fields.section
toPath: to }
})
console.log('Create redirect: ' + from + ' --> ' + to)
})
resolve()
}) })
})
// API: brizo, aquarius
await createSwaggerPages(createPage)
// API: squid-js
const lastRelease = result.data.squidJs.repository.releases.edges.filter(
({ node }) => !node.isPrerelease && !node.isDraft
)[0].node.releaseAssets.edges[0].node
await createTypeDocPage(
createPage,
result.data.squidJs.repository.name,
lastRelease.downloadUrl
) )
})
//
// create redirects
//
redirects.forEach(({ from, to }) => {
createRedirect({
fromPath: from,
redirectInBrowser: true,
toPath: to
})
console.log('Create redirect: ' + from + ' --> ' + to)
})
resolve()
})
)
})
} }
// //
// Create pages from TypeDoc json files // Create pages from TypeDoc json files
// //
const createTypeDocPage = async (createPage, name, downloadUrl) => { const createTypeDocPage = async (createPage, name, downloadUrl) => {
try { try {
const typedoc = await fetch(downloadUrl) const typedoc = await fetch(downloadUrl)
const typedocTemplate = path.resolve( const typedocTemplate = path.resolve('./src/templates/Typedoc/index.jsx')
'./src/templates/Typedoc/index.jsx' const slug = `/references/${name}/`
)
const slug = `/references/${name}/`
createPage({ createPage({
path: slug, path: slug,
component: typedocTemplate, component: typedocTemplate,
context: { context: {
slug, slug,
typedoc: await typedoc.json(), typedoc: await typedoc.json(),
// We define the classes here so the data object passed as page context // We define the classes here so the data object passed as page context
// is as small as possible. // is as small as possible.
// Caveat: no live update during development when these values are changed. // Caveat: no live update during development when these values are changed.
// //
// TODO: defining these classes for inclusion // TODO: defining these classes for inclusion
// needs to be handled somewhere else to keep // needs to be handled somewhere else to keep
// it generic for all TypeDoc specs // it generic for all TypeDoc specs
classes: [ classes: [
'ocean/Ocean', 'ocean/Ocean',
'ocean/OceanAccounts', 'ocean/OceanAccounts',
'ocean/OceanAssets', 'ocean/OceanAssets',
'ocean/OceanAgreements', 'ocean/OceanAgreements',
'ocean/OceanAgreementsConditions', 'ocean/OceanAgreementsConditions',
'ocean/OceanCompute', 'ocean/OceanCompute',
'ocean/OceanSecretStore', 'ocean/OceanSecretStore',
'ocean/OceanVersions', 'ocean/OceanVersions',
'ocean/Account', 'ocean/Account',
'ocean/DID', 'ocean/DID',
'ddo/DDO', 'ddo/DDO',
'ddo/Service', 'ddo/Service',
'aquarius/Aquarius', 'aquarius/Aquarius',
'brizo/Brizo', 'brizo/Brizo',
'keeper/Keeper', 'keeper/Keeper',
'keeper/ContractHandler', 'keeper/ContractHandler',
'keeper/EventHandler', 'keeper/EventHandler',
'keeper/Web3Provider', 'keeper/Web3Provider',
'models/Config', 'models/Config',
'models/Balance', 'models/Balance',
'ocean/utils/OceanUtils', 'ocean/utils/OceanUtils',
'ocean/utils/ServiceAgreement', 'ocean/utils/ServiceAgreement',
'ocean/utils/WebServiceConnector', 'ocean/utils/WebServiceConnector',
'utils/Logger' 'utils/Logger'
] ]
} }
}) })
} catch (error) { } catch (error) {
console.log(error.message) console.log(error.message)
} }
} }
// //
@ -257,77 +244,75 @@ const createTypeDocPage = async (createPage, name, downloadUrl) => {
// //
// https://github.com/swagger-api/swagger-js // https://github.com/swagger-api/swagger-js
const fetchSwaggerSpec = async (name) => { const fetchSwaggerSpec = async (name) => {
try { try {
const client = await Swagger( const client = await Swagger(
`https://${name}.commons.oceanprotocol.com/spec` `https://${name}.commons.oceanprotocol.com/spec`
) )
return client.spec // The resolved spec return client.spec // The resolved spec
// client.originalSpec // In case you need it // client.originalSpec // In case you need it
// client.errors // Any resolver errors // client.errors // Any resolver errors
// Tags interface // Tags interface
// client.apis.pet.addPet({id: 1, name: "bobby"}).then(...) // client.apis.pet.addPet({id: 1, name: "bobby"}).then(...)
// TryItOut Executor, with the `spec` already provided // TryItOut Executor, with the `spec` already provided
// client.execute({operationId: 'addPet', parameters: {id: 1, name: "bobby") }).then(...) // client.execute({operationId: 'addPet', parameters: {id: 1, name: "bobby") }).then(...)
} catch (error) { } catch (error) {
console.error(error.message) console.error(error.message)
} }
} }
const createSwaggerPages = async (createPage) => { const createSwaggerPages = async (createPage) => {
const swaggerComponents = ['aquarius', 'brizo'] const swaggerComponents = ['aquarius', 'brizo']
const apiSwaggerTemplate = path.resolve('./src/templates/Swagger/index.jsx') const apiSwaggerTemplate = path.resolve('./src/templates/Swagger/index.jsx')
const getSlug = (name) => { const getSlug = (name) => {
const slug = `/references/${name}/` const slug = `/references/${name}/`
return slug return slug
}
const specAquarius = await fetchSwaggerSpec(swaggerComponents[0])
const slugAquarius = getSlug(swaggerComponents[0])
createPage({
path: slugAquarius,
component: apiSwaggerTemplate,
context: {
slug: slugAquarius,
name: swaggerComponents[0],
api: specAquarius
} }
})
const specAquarius = await fetchSwaggerSpec(swaggerComponents[0]) const specBrizo = await fetchSwaggerSpec(swaggerComponents[1])
const slugAquarius = getSlug(swaggerComponents[0]) const slugBrizo = getSlug(swaggerComponents[1])
createPage({
path: slugBrizo,
component: apiSwaggerTemplate,
context: {
slug: slugBrizo,
name: swaggerComponents[1],
api: specBrizo
}
})
// Swagger Pet Store example
const petStoreSlug = '/references/petstore/'
try {
const client = await Swagger(`http://petstore.swagger.io/v2/swagger.json`)
createPage({ createPage({
path: slugAquarius, path: petStoreSlug,
component: apiSwaggerTemplate, component: apiSwaggerTemplate,
context: { context: {
slug: slugAquarius, slug: petStoreSlug,
name: swaggerComponents[0], api: client.spec
api: specAquarius }
}
}) })
} catch (error) {
const specBrizo = await fetchSwaggerSpec(swaggerComponents[1]) console.error(error.message)
const slugBrizo = getSlug(swaggerComponents[1]) }
createPage({
path: slugBrizo,
component: apiSwaggerTemplate,
context: {
slug: slugBrizo,
name: swaggerComponents[1],
api: specBrizo
}
})
// Swagger Pet Store example
const petStoreSlug = '/references/petstore/'
try {
const client = await Swagger(
`http://petstore.swagger.io/v2/swagger.json`
)
createPage({
path: petStoreSlug,
component: apiSwaggerTemplate,
context: {
slug: petStoreSlug,
api: client.spec
}
})
} catch (error) {
console.error(error.message)
}
} }

25009
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,82 +8,72 @@
"build": "gatsby build", "build": "gatsby build",
"start": "gatsby develop", "start": "gatsby develop",
"ssr": "npm run build && serve -s public/", "ssr": "npm run build && serve -s public/",
"format:js": "prettier --write '**/*.{js,jsx}'", "format": "prettier --ignore-path .gitignore './**/*.{css,scss,yml,js,jsx,ts,tsx,json}' --write",
"format:css": "prettier-stylelint --write --quiet 'src/**/*.{css,scss}'",
"format:md": "prettier --write '**/*.md'",
"format:yml": "prettier --write '**/*.{yml,yaml}'",
"format": "run-p format:js format:css format:md format:yml",
"lint:js": "eslint --ignore-path .gitignore --ignore-path .prettierignore --ext .js,.jsx .", "lint:js": "eslint --ignore-path .gitignore --ignore-path .prettierignore --ext .js,.jsx .",
"lint:css": "stylelint './src/**/*.{css,scss}'",
"lint:md": "markdownlint './**/*.{md,markdown}' --ignore './{node_modules,external,public,.cache}/**/*'", "lint:md": "markdownlint './**/*.{md,markdown}' --ignore './{node_modules,external,public,.cache}/**/*'",
"lint:yml": "prettier '**/*.{yml,yaml}' --list-different", "lint:yml": "prettier '**/*.{yml,yaml}' --list-different",
"lint": "run-p --continue-on-error lint:js lint:css lint:md lint:yml", "lint": "run-p --continue-on-error lint:js lint:md lint:yml",
"test": "npm run lint", "test": "npm run lint",
"deploy": "./scripts/deploy.sh" "deploy": "./scripts/deploy.sh"
}, },
"dependencies": { "dependencies": {
"@oceanprotocol/art": "^2.2.0", "@oceanprotocol/art": "^3.0.0",
"axios": "^0.19.2", "axios": "^0.19.2",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"gatsby": "^2.21.31", "gatsby": "^2.23.12",
"gatsby-image": "^2.4.3", "gatsby-image": "^2.4.9",
"gatsby-plugin-catch-links": "^2.3.1", "gatsby-plugin-catch-links": "^2.3.7",
"gatsby-plugin-google-analytics": "^2.3.1", "gatsby-plugin-google-analytics": "^2.3.6",
"gatsby-plugin-manifest": "^2.4.3", "gatsby-plugin-manifest": "^2.4.14",
"gatsby-plugin-offline": "^3.2.2", "gatsby-plugin-offline": "^3.2.13",
"gatsby-plugin-react-helmet": "^3.3.1", "gatsby-plugin-react-helmet": "^3.3.6",
"gatsby-plugin-sass": "^2.3.1", "gatsby-plugin-sass": "^2.3.7",
"gatsby-plugin-sharp": "^2.6.3", "gatsby-plugin-sharp": "^2.6.14",
"gatsby-plugin-sitemap": "^2.4.2", "gatsby-plugin-sitemap": "^2.4.7",
"gatsby-plugin-svgr": "^2.0.2", "gatsby-plugin-svgr": "^2.0.2",
"gatsby-plugin-webpack-size": "^1.0.0", "gatsby-plugin-webpack-size": "^1.0.0",
"gatsby-remark-autolink-headers": "^2.3.2", "gatsby-remark-autolink-headers": "^2.3.7",
"gatsby-remark-code-titles": "^1.1.0", "gatsby-remark-code-titles": "^1.1.0",
"gatsby-remark-component": "^1.1.3", "gatsby-remark-component": "^1.1.3",
"gatsby-remark-copy-linked-files": "^2.3.2", "gatsby-remark-copy-linked-files": "^2.3.7",
"gatsby-remark-embed-video": "^3.0.10", "gatsby-remark-embed-video": "^3.0.10",
"gatsby-remark-github": "^2.0.0", "gatsby-remark-github": "^2.0.0",
"gatsby-remark-images": "^3.3.3", "gatsby-remark-images": "^3.3.14",
"gatsby-remark-responsive-iframe": "^2.4.2", "gatsby-remark-responsive-iframe": "^2.4.7",
"gatsby-remark-smartypants": "^2.3.1", "gatsby-remark-smartypants": "^2.3.6",
"gatsby-remark-vscode": "^2.1.1", "gatsby-remark-vscode": "^2.1.2",
"gatsby-source-filesystem": "^2.3.3", "gatsby-source-filesystem": "^2.3.14",
"gatsby-source-graphql": "^2.5.1", "gatsby-source-graphql": "^2.5.7",
"gatsby-transformer-remark": "^2.8.8", "gatsby-transformer-remark": "^2.8.20",
"gatsby-transformer-sharp": "^2.5.2", "gatsby-transformer-sharp": "^2.5.7",
"gatsby-transformer-xml": "^2.3.1", "gatsby-transformer-xml": "^2.3.6",
"gatsby-transformer-yaml": "^2.4.1", "gatsby-transformer-yaml": "^2.4.6",
"giphy-js-sdk-core": "^1.0.6", "giphy-js-sdk-core": "^1.0.6",
"intersection-observer": "^0.10.0", "intersection-observer": "^0.11.0",
"react": "^16.13.1", "react": "^16.13.1",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-helmet": "^6.0.0", "react-helmet": "^6.1.0",
"react-scrollspy": "^3.4.2", "react-scrollspy": "^3.4.2",
"rehype-react": "^5.0.1", "rehype-react": "^6.0.0",
"remark": "^12.0.0", "remark": "^12.0.0",
"remark-github-plugin": "^1.3.1", "remark-github-plugin": "^1.4.0",
"remark-react": "^7.0.1", "remark-react": "^7.0.1",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"slugify": "^1.4.0", "slugify": "^1.4.4",
"smoothscroll-polyfill": "^0.4.4", "smoothscroll-polyfill": "^0.4.4",
"swagger-client": "^3.10.3" "swagger-client": "^3.10.9"
}, },
"devDependencies": { "devDependencies": {
"@svgr/webpack": "^5.4.0", "@svgr/webpack": "^5.4.0",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"eslint": "^7.0.0", "eslint": "^7.3.1",
"eslint-config-oceanprotocol": "^1.5.0", "eslint-config-oceanprotocol": "^1.5.0",
"eslint-config-prettier": "^6.11.0", "eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.3", "eslint-plugin-prettier": "^3.1.4",
"markdownlint-cli": "^0.23.0", "markdownlint-cli": "^0.23.2",
"node-sass": "^4.14.1", "node-sass": "^4.14.1",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^2.0.5", "prettier": "^2.0.5"
"prettier-stylelint": "^0.4.2",
"stylelint": "^13.3.3",
"stylelint-config-bigchaindb": "^1.2.2",
"stylelint-config-css-modules": "^2.2.0",
"stylelint-config-standard": "^20.0.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -3,11 +3,11 @@ import PropTypes from 'prop-types'
import styles from './Content.module.scss' import styles from './Content.module.scss'
const Content = ({ children }) => ( const Content = ({ children }) => (
<section className={styles.content}>{children}</section> <section className={styles.content}>{children}</section>
) )
Content.propTypes = { Content.propTypes = {
children: PropTypes.any.isRequired children: PropTypes.any.isRequired
} }
export default Content export default Content

View File

@ -1,11 +1,11 @@
@import 'variables'; @import 'variables';
.content { .content {
padding: 0 $spacer / 2; padding: 0 $spacer / 2;
max-width: $break-point--large; max-width: $break-point--large;
margin: auto; margin: auto;
@media (min-width: $break-point--small) { @media (min-width: $break-point--small) {
padding: 0 $spacer; padding: 0 $spacer;
} }
} }

View File

@ -5,22 +5,22 @@ import Repository from './Repository'
import styles from './DocContent.module.scss' import styles from './DocContent.module.scss'
const renderAst = new RehypeReact({ const renderAst = new RehypeReact({
createElement: React.createElement, createElement: React.createElement,
components: { repo: Repository } components: { repo: Repository }
}).Compiler }).Compiler
const DocContent = ({ html, htmlAst }) => const DocContent = ({ html, htmlAst }) =>
html ? ( html ? (
<div className={styles.docContent}>{renderAst(htmlAst)}</div> <div className={styles.docContent}>{renderAst(htmlAst)}</div>
) : ( ) : (
<div className={styles.empty}> <div className={styles.empty}>
This is a placeholder for now. Help creating it. This is a placeholder for now. Help creating it.
</div> </div>
) )
DocContent.propTypes = { DocContent.propTypes = {
html: PropTypes.string, html: PropTypes.string,
htmlAst: PropTypes.object htmlAst: PropTypes.object
} }
export default DocContent export default DocContent

View File

@ -1,70 +1,70 @@
@import 'variables'; @import 'variables';
.docContent { .docContent {
// handling long text, like URLs // handling long text, like URLs
overflow-wrap: break-word; overflow-wrap: break-word;
word-wrap: break-word; word-wrap: break-word;
word-break: break-word; word-break: break-word;
padding-bottom: $spacer / $line-height;
figcaption {
font-size: $font-size-small;
text-align: center;
color: $brand-grey-light;
margin-top: $spacer / 2;
}
> div > h1,
> div > h2 {
margin-top: $spacer * $line-height;
margin-bottom: $spacer / $line-height;
padding-bottom: $spacer / $line-height; padding-bottom: $spacer / $line-height;
border-bottom: 1px solid $brand-grey-lighter;
}
figcaption { table {
font-size: $font-size-small; overflow-wrap: normal;
text-align: center; word-wrap: normal;
color: $brand-grey-light; word-break: normal;
margin-top: $spacer / 2; }
// use blockquote for info blocks
blockquote {
padding: $spacer / 2;
background: lighten($brand-grey-light, 36%);
border-left: 0.25rem solid $brand-grey-light;
border-top-right-radius: $border-radius;
border-bottom-right-radius: $border-radius;
&,
p {
color: $brand-blue;
font-style: italic;
} }
> div > h1, p:last-child {
> div > h2 { margin-bottom: 0;
margin-top: $spacer * $line-height;
margin-bottom: $spacer / $line-height;
padding-bottom: $spacer / $line-height;
border-bottom: 1px solid $brand-grey-lighter;
}
table {
overflow-wrap: normal;
word-wrap: normal;
word-break: normal;
}
// use blockquote for info blocks
blockquote {
padding: $spacer / 2;
background: lighten($brand-grey-light, 36%);
border-left: .25rem solid $brand-grey-light;
border-top-right-radius: $border-radius;
border-bottom-right-radius: $border-radius;
&,
p {
color: $brand-blue;
font-style: italic;
}
p:last-child {
margin-bottom: 0;
}
} }
}
} }
.empty { .empty {
font-style: italic; font-style: italic;
margin-bottom: $spacer * 2; margin-bottom: $spacer * 2;
} }
:global(.footnotes) { :global(.footnotes) {
font-size: $font-size-small; font-size: $font-size-small;
p { p {
margin: 0; margin: 0;
} }
} }
:global(.footnote-ref) { :global(.footnote-ref) {
font-size: $font-size-mini; font-size: $font-size-mini;
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
padding-left: .2rem; padding-left: 0.2rem;
padding-right: .2rem; padding-right: 0.2rem;
display: inline-block; display: inline-block;
} }

View File

@ -5,40 +5,38 @@ import styles from './DocFooter.module.scss'
import { social, githubContentPath, githubDevOceanPath } from '../../config' import { social, githubContentPath, githubDevOceanPath } from '../../config'
export default function DocFooter({ post, url, externalName }) { export default function DocFooter({ post, url, externalName }) {
let path let path
if (post) { if (post) {
const { sourceInstanceName } = post.parent const { sourceInstanceName } = post.parent
switch (sourceInstanceName) { switch (sourceInstanceName) {
case 'dev-ocean': case 'dev-ocean':
path = githubDevOceanPath path = githubDevOceanPath
externalName = sourceInstanceName externalName = sourceInstanceName
break break
default: default:
path = githubContentPath path = githubContentPath
}
url = `${path}/${post.parent.relativePath}`
} }
return ( url = `${path}/${post.parent.relativePath}`
<footer className={styles.footer}> }
<a href={social.Discord}> Ask a question on Discord</a>
<a href={url} className={post && !post.html ? styles.active : null}> return (
<Pencil /> Edit this page on GitHub <footer className={styles.footer}>
{externalName && ( <a href={social.Discord}> Ask a question on Discord</a>
<span className={styles.externalRepoName}> <a href={url} className={post && !post.html ? styles.active : null}>
{externalName} <Pencil /> Edit this page on GitHub
</span> {externalName && (
)} <span className={styles.externalRepoName}>{externalName}</span>
</a> )}
</footer> </a>
) </footer>
)
} }
DocFooter.propTypes = { DocFooter.propTypes = {
post: PropTypes.object, post: PropTypes.object,
url: PropTypes.string, url: PropTypes.string,
externalName: PropTypes.string externalName: PropTypes.string
} }

View File

@ -1,54 +1,54 @@
@import 'variables'; @import 'variables';
.footer { .footer {
margin-top: $spacer; margin-top: $spacer;
margin-bottom: $spacer; margin-bottom: $spacer;
font-size: $font-size-small; font-size: $font-size-small;
text-align: center; text-align: center;
@media (min-width: $break-point--small) {
display: flex;
justify-content: space-between;
}
a {
font-family: $font-family-button;
font-weight: $font-weight-bold;
text-transform: uppercase;
color: $brand-grey-light;
display: block;
margin-bottom: $spacer / 2;
@media (min-width: $break-point--small) { @media (min-width: $break-point--small) {
display: flex; margin-bottom: 0;
justify-content: space-between;
} }
a { &:hover,
font-family: $font-family-button; &:focus {
font-weight: $font-weight-bold; color: $brand-pink;
text-transform: uppercase;
color: $brand-grey-light;
display: block;
margin-bottom: $spacer / 2;
@media (min-width: $break-point--small) {
margin-bottom: 0;
}
&:hover,
&:focus {
color: $brand-pink;
}
svg {
display: inline-block;
margin-right: $spacer / 10;
margin-bottom: -1px;
fill: $brand-grey-light;
}
&:last-child {
margin-bottom: 0;
}
} }
svg {
display: inline-block;
margin-right: $spacer / 10;
margin-bottom: -1px;
fill: $brand-grey-light;
}
&:last-child {
margin-bottom: 0;
}
}
} }
.active { .active {
color: $brand-pink !important; // stylelint-disable-line declaration-no-important color: $brand-pink !important; // stylelint-disable-line declaration-no-important
} }
.externalRepoName { .externalRepoName {
font-family: $font-family-monospace; font-family: $font-family-monospace;
font-weight: $font-weight-base; font-weight: $font-weight-base;
font-size: $font-size-mini; font-size: $font-size-mini;
text-transform: none; text-transform: none;
margin-left: $spacer / 4; margin-left: $spacer / 4;
} }

View File

@ -5,25 +5,23 @@ import remarkReact from 'remark-react'
import styles from './DocHeader.module.scss' import styles from './DocHeader.module.scss'
const DocHeader = ({ title, description, prepend }) => { const DocHeader = ({ title, description, prepend }) => {
const descriptionHtml = const descriptionHtml =
description && remark().use(remarkReact).processSync(description).result description && remark().use(remarkReact).processSync(description).result
return ( return (
<header className={styles.header}> <header className={styles.header}>
<h1 className={styles.title}> <h1 className={styles.title}>
{title} {prepend && prepend} {title} {prepend && prepend}
</h1> </h1>
{description && ( {description && <div className={styles.lead}>{descriptionHtml}</div>}
<div className={styles.lead}>{descriptionHtml}</div> </header>
)} )
</header>
)
} }
DocHeader.propTypes = { DocHeader.propTypes = {
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
description: PropTypes.string, description: PropTypes.string,
prepend: PropTypes.any prepend: PropTypes.any
} }
export default DocHeader export default DocHeader

View File

@ -1,25 +1,25 @@
@import 'variables'; @import 'variables';
.header { .header {
padding-top: $spacer; padding-top: $spacer;
margin-bottom: $spacer; margin-bottom: $spacer;
@media screen and (min-width: $break-point--small) { @media screen and (min-width: $break-point--small) {
padding-top: $spacer * $line-height; padding-top: $spacer * $line-height;
margin-bottom: $spacer * $line-height; margin-bottom: $spacer * $line-height;
} }
} }
.title { .title {
font-size: $font-size-h1 / 1.3; font-size: $font-size-h1 / 1.3;
margin-top: 0; margin-top: 0;
margin-bottom: $spacer / $line-height; margin-bottom: $spacer / $line-height;
@media screen and (min-width: $break-point--small) { @media screen and (min-width: $break-point--small) {
font-size: $font-size-h1; font-size: $font-size-h1;
} }
} }
.lead { .lead {
font-size: $font-size-large; font-size: $font-size-large;
} }

View File

@ -3,14 +3,14 @@ import PropTypes from 'prop-types'
import styles from './DocToc.module.scss' import styles from './DocToc.module.scss'
const DocToc = ({ tableOfContents }) => ( const DocToc = ({ tableOfContents }) => (
<aside <aside
className={styles.toc} className={styles.toc}
dangerouslySetInnerHTML={{ __html: tableOfContents }} dangerouslySetInnerHTML={{ __html: tableOfContents }}
/> />
) )
DocToc.propTypes = { DocToc.propTypes = {
tableOfContents: PropTypes.string.isRequired tableOfContents: PropTypes.string.isRequired
} }
export default DocToc export default DocToc

View File

@ -1,15 +1,15 @@
@import 'variables'; @import 'variables';
.toc { .toc {
background: darken($brand-white, 2%); background: darken($brand-white, 2%);
padding: $spacer / 2; padding: $spacer / 2;
margin-bottom: $spacer * 2; margin-bottom: $spacer * 2;
@media screen and (min-width: $break-point--small) { @media screen and (min-width: $break-point--small) {
padding: $spacer / $line-height $spacer; padding: $spacer / $line-height $spacer;
} }
ul { ul {
margin-bottom: 0; margin-bottom: 0;
} }
} }

View File

@ -5,59 +5,59 @@ import Content from '../components/Content'
import styles from './Footer.module.scss' import styles from './Footer.module.scss'
const query = graphql` const query = graphql`
query { query {
site { site {
siteMetadata { siteMetadata {
siteCompany siteCompany
social { social {
Site Site
Blog Blog
GitHub GitHub
Twitter Twitter
Discord Discord
Port Port
Telegram Telegram
}
}
} }
}
} }
}
` `
const FooterSocial = ({ social }) => ( const FooterSocial = ({ social }) => (
<nav className={styles.links}> <nav className={styles.links}>
{Object.keys(social).map((key) => ( {Object.keys(social).map((key) => (
<a key={key} href={social[key]}> <a key={key} href={social[key]}>
{key} {key}
</a> </a>
))} ))}
</nav> </nav>
) )
FooterSocial.propTypes = { FooterSocial.propTypes = {
social: PropTypes.object social: PropTypes.object
} }
const Footer = () => ( const Footer = () => (
<StaticQuery <StaticQuery
query={query} query={query}
render={(data) => { render={(data) => {
const { siteCompany, social } = data.site.siteMetadata const { siteCompany, social } = data.site.siteMetadata
return ( return (
<footer className={styles.footer}> <footer className={styles.footer}>
<Content> <Content>
<small> <small>
&copy; {new Date().getFullYear()}{' '} &copy; {new Date().getFullYear()}{' '}
<a href={social.site}>{siteCompany}</a> &mdash; All <a href={social.site}>{siteCompany}</a> &mdash; All Rights
Rights Reserved Reserved
</small> </small>
<FooterSocial social={social} /> <FooterSocial social={social} />
</Content> </Content>
</footer> </footer>
) )
}} }}
/> />
) )
export default Footer export default Footer

View File

@ -1,58 +1,58 @@
@import 'variables'; @import 'variables';
.footer { .footer {
color: $brand-grey-light; color: $brand-grey-light;
width: 100%; width: 100%;
text-align: center; text-align: center;
margin-top: $spacer; margin-top: $spacer;
padding-top: $spacer; padding-top: $spacer;
padding-bottom: $spacer; padding-bottom: $spacer;
> section { > section {
align-self: flex-end; align-self: flex-end;
@media screen and (min-width: $break-point--small) { @media screen and (min-width: $break-point--small) {
text-align: left; text-align: left;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
}
} }
}
&, &,
small { small {
font-size: $font-size-small; font-size: $font-size-small;
}
a {
color: inherit;
&:hover,
&:focus {
color: $brand-grey;
} }
}
a { svg {
color: inherit; display: inline-block;
width: $font-size-large;
&:hover, height: $font-size-large;
&:focus { }
color: $brand-grey;
}
}
svg {
display: inline-block;
width: $font-size-large;
height: $font-size-large;
}
} }
.links { .links {
margin-top: $spacer / 2; margin-top: $spacer / 2;
@media screen and (min-width: $break-point--small) { @media screen and (min-width: $break-point--small) {
text-align: right; text-align: right;
margin-top: 0; margin-top: 0;
} }
a { a {
margin: 0 $spacer / 2; margin: 0 $spacer / 2;
display: inline-block; display: inline-block;
&:last-child { &:last-child {
margin-right: 0; margin-right: 0;
}
} }
}
} }

View File

@ -1,59 +1,59 @@
import React from 'react' import React from 'react'
import { Link, StaticQuery, graphql } from 'gatsby' import { Link, StaticQuery, graphql } from 'gatsby'
import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo-white.svg' import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
import styles from './Header.module.scss' import styles from './Header.module.scss'
const query = graphql` const query = graphql`
query { query {
site { site {
siteMetadata { siteMetadata {
siteTitle siteTitle
} }
}
allSectionsYaml {
edges {
node {
title
description
link
}
}
}
} }
allSectionsYaml {
edges {
node {
title
description
link
}
}
}
}
` `
const Header = () => ( const Header = () => (
<StaticQuery <StaticQuery
query={query} query={query}
render={(data) => { render={(data) => {
const { siteTitle } = data.site.siteMetadata const { siteTitle } = data.site.siteMetadata
const sections = data.allSectionsYaml.edges const sections = data.allSectionsYaml.edges
return ( return (
<header className={styles.header}> <header className={styles.header}>
<div className={styles.headerContent}> <div className={styles.headerContent}>
<Link to="/" className={styles.headerLogo}> <Link to="/" className={styles.headerLogo}>
<Logo className={styles.headerLogoImage} /> <Logo className={styles.headerLogoImage} />
<h1 className={styles.headerTitle}>{siteTitle}</h1> <h1 className={styles.headerTitle}>{siteTitle}</h1>
</Link> </Link>
<nav className={styles.headerMenu}> <nav className={styles.headerMenu}>
{sections.map(({ node }) => ( {sections.map(({ node }) => (
<Link <Link
key={node.title} key={node.title}
to={node.link} to={node.link}
className={styles.section} className={styles.section}
> >
{node.title} {node.title}
</Link> </Link>
))} ))}
</nav> </nav>
</div> </div>
</header> </header>
) )
}} }}
/> />
) )
export default Header export default Header

View File

@ -1,89 +1,83 @@
@import 'variables'; @import 'variables';
.header { .header {
background: $brand-black background: $brand-grey-dimmed url('@oceanprotocol/art/waves/waves.svg')
url('@oceanprotocol/art/mantaray/mantaray-back.svg') no-repeat center -6rem; no-repeat center -3rem;
background-size: cover; background-size: cover;
width: 100%; width: 100%;
padding: $spacer / 2 0; padding: $spacer / 2 0;
} }
.headerContent { .headerContent {
composes: content from './Content.module.scss'; composes: content from './Content.module.scss';
display: flex; display: flex;
align-items: center; align-items: center;
} }
.headerLogo { .headerLogo {
display: flex; display: flex;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
&:hover, &:hover,
&:focus, &:focus,
&:active { &:active {
transform: none; transform: none;
} }
} }
.headerLogoImage { .headerLogoImage {
width: 4rem; width: 4rem;
height: 4rem; height: 4rem;
fill: #fff; margin: 0;
margin: 0;
} }
.headerTitle { .headerTitle {
font-size: $font-size-h3; font-size: $font-size-h3;
color: $brand-grey-light; color: $brand-grey-light;
margin-left: $spacer / 2; margin-left: $spacer / 2;
display: none; display: none;
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
display: inline-block; display: inline-block;
} }
} }
.headerMenu { .headerMenu {
flex: 1; flex: 1;
justify-self: flex-end; justify-self: flex-end;
text-align: right; text-align: right;
white-space: nowrap; white-space: nowrap;
overflow-y: hidden; overflow-y: hidden;
overflow-x: auto; overflow-x: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
margin-right: -($spacer / 2); margin-right: -($spacer / 2);
padding-right: $spacer; padding-right: $spacer;
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
padding-right: 0; padding-right: 0;
margin-right: 0; margin-right: 0;
} }
&::-webkit-scrollbar, &::-webkit-scrollbar,
&::-moz-scrollbar { &::-moz-scrollbar {
display: none; display: none;
} }
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 3px; width: 3px;
height: 3px; height: 3px;
transition: opacity .2s ease-out; transition: opacity 0.2s ease-out;
} }
} }
.section { .section {
display: inline-block; display: inline-block;
margin: 0 $spacer / 2; margin: 0 $spacer / 2;
font-family: $font-family-button; font-family: $font-family-button;
color: $brand-grey-lighter; color: $brand-grey;
&:last-child { &:last-child {
margin-right: 0; margin-right: 0;
} }
&:hover,
&:focus {
color: $brand-white;
}
} }

View File

@ -1,37 +1,35 @@
import React from 'react' import React from 'react'
import { StaticQuery, graphql } from 'gatsby' import { StaticQuery, graphql } from 'gatsby'
import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo-white.svg' import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
import Content from '../components/Content' import Content from '../components/Content'
import styles from './HeaderHome.module.scss' import styles from './HeaderHome.module.scss'
const HeaderHome = () => ( const HeaderHome = () => (
<StaticQuery <StaticQuery
query={graphql` query={graphql`
query { query {
site { site {
siteMetadata { siteMetadata {
siteTitle siteTitle
siteDescription siteDescription
} }
} }
} }
`} `}
render={(data) => { render={(data) => {
const { siteTitle, siteDescription } = data.site.siteMetadata const { siteTitle, siteDescription } = data.site.siteMetadata
return ( return (
<header className={styles.header}> <header className={styles.header}>
<Content> <Content>
<Logo className={styles.headerLogo} /> <Logo className={styles.headerLogo} />
<h1 className={styles.headerTitle}>{siteTitle}</h1> <h1 className={styles.headerTitle}>{siteTitle}</h1>
<p className={styles.headerDescription}> <p className={styles.headerDescription}>{siteDescription}</p>
{siteDescription} </Content>
</p> </header>
</Content> )
</header> }}
) />
}}
/>
) )
export default HeaderHome export default HeaderHome

View File

@ -2,49 +2,47 @@
@import 'animations'; @import 'animations';
.header { .header {
background: $brand-black background: $brand-grey-dimmed url('@oceanprotocol/art/waves/waves.svg')
url('@oceanprotocol/art/mantaray/mantaray-back.svg') no-repeat center no-repeat center 10rem;
4rem; background-size: cover;
background-size: cover; width: 100%;
width: 100%; padding: $spacer * 2 0;
padding: $spacer * 2 0; min-height: 30rem;
min-height: 30rem; text-align: center;
color: $brand-white; display: flex;
text-align: center; justify-content: center;
display: flex; align-items: center;
justify-content: center;
align-items: center;
} }
.headerLogo, .headerLogo,
.headerTitle, .headerTitle,
.headerDescription { .headerDescription {
animation: fadeInUp .6s ease-out backwards; animation: fadeInUp 0.6s ease-out backwards;
} }
.headerLogo { .headerLogo {
width: 5rem; width: 5rem;
height: 5rem; height: 5rem;
} }
.headerTitle { .headerTitle {
margin-bottom: $spacer; margin-bottom: $spacer;
font-size: $font-size-h2; font-size: $font-size-h2;
animation-delay: .2s; animation-delay: 0.2s;
@media (min-width: $break-point--small) { @media (min-width: $break-point--small) {
font-size: $font-size-h1; font-size: $font-size-h1;
} }
} }
.headerDescription { .headerDescription {
margin-bottom: $spacer * 4; margin-bottom: $spacer * 4;
max-width: $break-point--small; max-width: $break-point--small;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
animation-delay: .4s; animation-delay: 0.4s;
@media (min-width: $break-point--small) { @media (min-width: $break-point--small) {
font-size: $font-size-large; font-size: $font-size-large;
} }
} }

View File

@ -5,20 +5,20 @@ import Content from './Content'
import styles from './HeaderSection.module.scss' import styles from './HeaderSection.module.scss'
const HeaderSection = ({ title }) => ( const HeaderSection = ({ title }) => (
<aside className={styles.headerSection}> <aside className={styles.headerSection}>
<Content> <Content>
<h1 className={styles.headerSectionTitle}> <h1 className={styles.headerSectionTitle}>
<Link className={styles.rootLink} to="/"> <Link className={styles.rootLink} to="/">
/ /
</Link> </Link>
{title} {title}
</h1> </h1>
</Content> </Content>
</aside> </aside>
) )
HeaderSection.propTypes = { HeaderSection.propTypes = {
title: PropTypes.PropTypes.oneOfType([PropTypes.array, PropTypes.string]) title: PropTypes.PropTypes.oneOfType([PropTypes.array, PropTypes.string])
} }
export default HeaderSection export default HeaderSection

View File

@ -1,35 +1,35 @@
@import 'variables'; @import 'variables';
.headerSection { .headerSection {
border-bottom: .1rem solid $brand-grey-lighter; border-bottom: 0.1rem solid $brand-grey-lighter;
} }
.headerSectionTitle { .headerSectionTitle {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
padding: $spacer / $line-height 0; padding: $spacer / $line-height 0;
font-size: $font-size-h3; font-size: $font-size-h3;
color: $brand-grey-light; color: $brand-grey-light;
:global(.concepts) & { :global(.concepts) & {
color: $brand-purple; color: $brand-purple;
} }
:global(.setup) & { :global(.setup) & {
color: $brand-blue; color: $brand-blue;
} }
:global(.tutorials) & { :global(.tutorials) & {
color: $orange; color: $orange;
} }
:global(.references) & { :global(.references) & {
color: $green; color: $green;
} }
} }
.rootLink { .rootLink {
display: inline-block; display: inline-block;
margin-right: $spacer / 4; margin-right: $spacer / 4;
color: inherit; color: inherit;
} }

View File

@ -4,20 +4,20 @@ import Header from './Header'
import Footer from './Footer' import Footer from './Footer'
const Layout = ({ children, header }) => { const Layout = ({ children, header }) => {
const headerElement = header || <Header /> const headerElement = header || <Header />
return ( return (
<> <>
{headerElement} {headerElement}
{children} {children}
<Footer /> <Footer />
</> </>
) )
} }
Layout.propTypes = { Layout.propTypes = {
children: PropTypes.node.isRequired, children: PropTypes.node.isRequired,
header: PropTypes.element header: PropTypes.element
} }
export default Layout export default Layout

View File

@ -4,43 +4,41 @@ import Repository from './Repository'
import styles from './QuickRun.module.scss' import styles from './QuickRun.module.scss'
const QuickRun = () => ( const QuickRun = () => (
<StaticQuery <StaticQuery
query={graphql` query={graphql`
query { query {
allMarkdownRemark( allMarkdownRemark(filter: { fields: { slug: { eq: "/quickrun/" } } }) {
filter: { fields: { slug: { eq: "/quickrun/" } } } edges {
) { node {
edges { html
node {
html
}
}
}
} }
`} }
render={(data) => ( }
<aside className={styles.quickrun}> }
<header className={styles.header}> `}
<h1 className={styles.tldr}>TL;DR</h1> render={(data) => (
<strong> <aside className={styles.quickrun}>
Wanna quickly get an Ocean network with all{' '} <header className={styles.header}>
<Link to="/concepts/components/">core components</Link>{' '} <h1 className={styles.tldr}>TL;DR</h1>
running on your machine? <strong>
</strong> Wanna quickly get an Ocean network with all{' '}
</header> <Link to="/concepts/components/">core components</Link> running on
your machine?
</strong>
</header>
<div className={styles.docker}> <div className={styles.docker}>
<div <div
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data.allMarkdownRemark.edges[0].node.html __html: data.allMarkdownRemark.edges[0].node.html
}} }}
/> />
<Repository name="barge" /> <Repository name="barge" />
</div> </div>
</aside> </aside>
)} )}
/> />
) )
export default QuickRun export default QuickRun

View File

@ -1,58 +1,58 @@
@import 'variables'; @import 'variables';
.quickrun { .quickrun {
padding-top: $spacer * 4; padding-top: $spacer * 4;
padding-bottom: $spacer * 2.5; padding-bottom: $spacer * 2.5;
text-align: center; text-align: center;
> div { > div {
text-align: left; text-align: left;
margin-top: $spacer / $line-height; margin-top: $spacer / $line-height;
} }
} }
.header, .header,
.docker { .docker {
margin: auto; margin: auto;
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
max-width: 33rem; max-width: 33rem;
} }
} }
.header { .header {
margin-bottom: $spacer; margin-bottom: $spacer;
} }
.docker { .docker {
@media (min-width: $break-point--large) { @media (min-width: $break-point--large) {
max-width: none; max-width: none;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
> div, > div,
> article { > article {
flex: 0 0 48%; flex: 0 0 48%;
margin: 0; margin: 0;
}
pre {
margin: 0;
code {
padding: $spacer / 1.1;
}
}
} }
pre {
margin: 0;
code {
padding: $spacer / 1.1;
}
}
}
} }
.tldr { .tldr {
display: block; display: block;
margin-bottom: $spacer / 2; margin-bottom: $spacer / 2;
font-size: $font-size-h4; font-size: $font-size-h4;
+ strong { + strong {
color: $brand-grey-light; color: $brand-grey-light;
} }
} }

View File

@ -4,27 +4,23 @@ import Repository from '../Repository'
import styles from './RepositoryList.module.scss' import styles from './RepositoryList.module.scss'
const RepositoryList = ({ repositories }) => ( const RepositoryList = ({ repositories }) => (
<div className={styles.repositoryCategory}> <div className={styles.repositoryCategory}>
{repositories.map(({ node }) => ( {repositories.map(({ node }) => (
<div key={node.id}> <div key={node.id}>
<h3 className={styles.repositoryCategoryTitle}>{node.group}</h3> <h3 className={styles.repositoryCategoryTitle}>{node.group}</h3>
<div className={styles.repositoryList}> <div className={styles.repositoryList}>
{node.items.map((item) => ( {node.items.map((item) => (
<Repository <Repository key={item.name} name={item.name} links={item.links} />
key={item.name} ))}
name={item.name} </div>
links={item.links} </div>
/> ))}
))} </div>
</div>
</div>
))}
</div>
) )
RepositoryList.propTypes = { RepositoryList.propTypes = {
repositories: PropTypes.array.isRequired repositories: PropTypes.array.isRequired
} }
export default RepositoryList export default RepositoryList

View File

@ -1,74 +1,74 @@
@import 'variables'; @import 'variables';
.repositoryList { .repositoryList {
white-space: nowrap; white-space: nowrap;
overflow-y: hidden; overflow-y: hidden;
overflow-x: auto; overflow-x: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
margin-left: calc(-50vw + 50%); margin-left: calc(-50vw + 50%);
margin-right: calc(-50vw + 50%); margin-right: calc(-50vw + 50%);
display: flex; display: flex;
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
margin-left: $spacer; margin-left: $spacer;
border-left: 1px solid $brand-grey-lighter; border-left: 1px solid $brand-grey-lighter;
padding-left: $spacer; padding-left: $spacer;
padding-top: $spacer / 4; padding-top: $spacer / 4;
}
article {
white-space: normal;
flex: 0 0 90vw;
max-width: 25rem;
margin-left: $spacer;
margin-bottom: $spacer / 4;
&:first-child {
margin-left: $spacer * 1.4;
@media (min-width: $break-point--medium) {
margin-left: 0;
}
} }
}
article { // add final right margin
white-space: normal; &:after {
flex: 0 0 90vw; content: '';
max-width: 25rem; flex: 0 0 $spacer;
margin-left: $spacer; }
margin-bottom: $spacer / 4;
&:first-child { // custom scrollbar
margin-left: $spacer * 1.4; &::-webkit-scrollbar,
&::-moz-scrollbar {
display: none;
}
@media (min-width: $break-point--medium) { &::-webkit-scrollbar {
margin-left: 0; opacity: 0;
} width: 7px;
} height: 7px;
} transition: opacity 0.2s ease-out;
}
// add final right margin
&:after {
content: '';
flex: 0 0 $spacer;
}
// custom scrollbar
&::-webkit-scrollbar,
&::-moz-scrollbar {
display: none;
}
&:hover {
&::-webkit-scrollbar { &::-webkit-scrollbar {
opacity: 0; opacity: 1;
width: 7px;
height: 7px;
transition: opacity .2s ease-out;
} }
&:hover { &::-webkit-scrollbar-thumb {
&::-webkit-scrollbar { background: lighten($brand-grey-light, 30%);
opacity: 1;
}
&::-webkit-scrollbar-thumb {
background: lighten($brand-grey-light, 30%);
}
&::-webkit-scrollbar-track {
background: $brand-white;
}
} }
&::-webkit-scrollbar-track {
background: $brand-white;
}
}
} }
.repositoryCategoryTitle { .repositoryCategoryTitle {
width: 100%; width: 100%;
font-size: $font-size-h4; font-size: $font-size-h4;
color: $brand-grey-light; color: $brand-grey-light;
margin-bottom: $spacer / 2; margin-bottom: $spacer / 2;
} }

View File

@ -4,55 +4,51 @@ import RepositoryList from './RepositoryList'
import styles from './index.module.scss' import styles from './index.module.scss'
const query = graphql` const query = graphql`
query { query {
allRepositoriesYaml { allRepositoriesYaml {
edges { edges {
node { node {
id id
group group
items { items {
name name
links { links {
name name
url url
}
}
}
} }
}
} }
}
} }
}
` `
const Repositories = () => ( const Repositories = () => (
<StaticQuery <StaticQuery
query={query} query={query}
render={(data) => { render={(data) => {
const repositories = data.allRepositoriesYaml.edges const repositories = data.allRepositoriesYaml.edges
return ( return (
<div className={styles.repositories}> <div className={styles.repositories}>
<header> <header>
<h1 className={styles.repositoriesTitle}> <h1 className={styles.repositoriesTitle}>Repositories</h1>
Repositories <p className={styles.repositoriesText}>
</h1> <strong>
<p className={styles.repositoriesText}> Most of our repositories are open source and we listed the key
<strong> repositories here. Start with the{' '}
Most of our repositories are open source and we <Link to="/concepts/components/">software components</Link>{' '}
listed the key repositories here. Start with the{' '} document for an introduction to the components found in a
<Link to="/concepts/components/"> typical Ocean network.
software components </strong>
</Link>{' '} </p>
document for an introduction to the components </header>
found in a typical Ocean network.
</strong>
</p>
</header>
<RepositoryList repositories={repositories} /> <RepositoryList repositories={repositories} />
</div> </div>
) )
}} }}
/> />
) )
export default Repositories export default Repositories

View File

@ -1,26 +1,26 @@
@import 'variables'; @import 'variables';
.repositories { .repositories {
margin-top: $spacer * 2; margin-top: $spacer * 2;
> header { > header {
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
max-width: 33rem; max-width: 33rem;
margin: auto; margin: auto;
}
} }
}
} }
.repositoriesTitle { .repositoriesTitle {
text-align: center; text-align: center;
display: block; display: block;
margin-top: 0; margin-top: 0;
margin-bottom: $spacer / 2; margin-bottom: $spacer / 2;
font-size: $font-size-h3; font-size: $font-size-h3;
} }
.repositoriesText { .repositoriesText {
text-align: center; text-align: center;
margin-bottom: $spacer; margin-bottom: $spacer;
color: $brand-grey-light; color: $brand-grey-light;
} }

View File

@ -3,22 +3,22 @@ import PropTypes from 'prop-types'
import styles from './Links.module.scss' import styles from './Links.module.scss'
export default function Links({ links, url }) { export default function Links({ links, url }) {
return ( return (
<ul className={styles.links}> <ul className={styles.links}>
<li> <li>
<a href={url}>GitHub</a> <a href={url}>GitHub</a>
</li> </li>
{links && {links &&
links.map((link) => ( links.map((link) => (
<li key={link.url}> <li key={link.url}>
<a href={link.url}>{link.name}</a> <a href={link.url}>{link.name}</a>
</li> </li>
))} ))}
</ul> </ul>
) )
} }
Links.propTypes = { Links.propTypes = {
links: PropTypes.array, links: PropTypes.array,
url: PropTypes.string.isRequired url: PropTypes.string.isRequired
} }

View File

@ -1,23 +1,23 @@
@import 'variables'; @import 'variables';
.links { .links {
margin: 0; margin: 0;
padding: 0;
margin-left: -($spacer / $line-height);
width: 80%;
li {
display: inline-block;
padding: 0; padding: 0;
margin-left: -($spacer / $line-height); margin-left: $spacer / $line-height;
width: 80%;
li { &:before {
display: inline-block; display: none;
padding: 0;
margin-left: $spacer / $line-height;
&:before {
display: none;
}
} }
}
a { a {
font-family: $font-family-button; font-family: $font-family-button;
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
} }
} }

View File

@ -6,83 +6,83 @@ import { ReactComponent as Forks } from '../../images/forks.svg'
import styles from './Numbers.module.scss' import styles from './Numbers.module.scss'
export default class Numbers extends PureComponent { export default class Numbers extends PureComponent {
static propTypes = { static propTypes = {
stargazers: PropTypes.object.isRequired, stargazers: PropTypes.object.isRequired,
forkCount: PropTypes.number.isRequired, forkCount: PropTypes.number.isRequired,
url: PropTypes.string.isRequired, url: PropTypes.string.isRequired,
name: PropTypes.string.isRequired name: PropTypes.string.isRequired
} }
state = { state = {
forks: this.props.forkCount, forks: this.props.forkCount,
stars: this.props.stargazers.totalCount stars: this.props.stargazers.totalCount
} }
url = 'https://oceanprotocol-github.now.sh' url = 'https://oceanprotocol-github.now.sh'
signal = axios.CancelToken.source() signal = axios.CancelToken.source()
componentDidMount() { componentDidMount() {
this.fetchNumbers() this.fetchNumbers()
} }
componentWillUnmount() { componentWillUnmount() {
this.signal.cancel() this.signal.cancel()
} }
fetchNumbers = async () => { fetchNumbers = async () => {
try { try {
const response = await axios({ const response = await axios({
method: 'get', method: 'get',
url: this.url, url: this.url,
timeout: 10000, // 10 sec. timeout: 10000, // 10 sec.
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}
})
const repo = response.data
.map((item) => {
if (item.name === this.props.name) {
return item
}
})
.filter((n) => n)
const { forks, stars } = repo
// update state only when numbers have changed
if (forks && forks !== this.props.forkCount) {
this.setState({ forks })
}
if (stars && stars !== this.props.stargazers.totalCount) {
this.setState({ stars })
}
} catch (error) {
if (axios.isCancel(error)) {
return null
} else {
console.log(error.message) // eslint-disable-line no-console
}
} }
} })
render() { const repo = response.data
const { url } = this.props .map((item) => {
const { forks, stars } = this.state if (item.name === this.props.name) {
return item
}
})
.filter((n) => n)
return ( const { forks, stars } = repo
<aside className={styles.repositorynumbers}>
<a href={`${url}/stargazers`} title="Show Stargazers"> // update state only when numbers have changed
<Star /> <span>{stars}</span> if (forks && forks !== this.props.forkCount) {
</a> this.setState({ forks })
{forks > 0 && ( }
<a href={`${url}/network`} title="Show Forks">
<Forks /> <span>{forks}</span> if (stars && stars !== this.props.stargazers.totalCount) {
</a> this.setState({ stars })
)} }
</aside> } catch (error) {
) if (axios.isCancel(error)) {
return null
} else {
console.log(error.message) // eslint-disable-line no-console
}
} }
}
render() {
const { url } = this.props
const { forks, stars } = this.state
return (
<aside className={styles.repositorynumbers}>
<a href={`${url}/stargazers`} title="Show Stargazers">
<Star /> <span>{stars}</span>
</a>
{forks > 0 && (
<a href={`${url}/network`} title="Show Forks">
<Forks /> <span>{forks}</span>
</a>
)}
</aside>
)
}
} }

View File

@ -1,35 +1,35 @@
@import 'variables'; @import 'variables';
.repositorynumbers { .repositorynumbers {
font-size: $font-size-small; font-size: $font-size-small;
margin-left: -($spacer / 4); margin-left: -($spacer / 4);
flex: 1; flex: 1;
text-align: right; text-align: right;
width: 20%; width: 20%;
a { a {
color: $brand-grey-light; color: $brand-grey-light;
margin-left: $spacer / 4; margin-left: $spacer / 4;
display: inline-block; display: inline-block;
&:hover, &:hover,
&:focus { &:focus {
color: $brand-pink; color: $brand-pink;
transform: none; transform: none;
svg { svg {
fill: $brand-pink; fill: $brand-pink;
} }
}
span {
margin-left: -.15rem;
}
} }
svg { span {
display: inline-block; margin-left: -0.15rem;
fill: $brand-grey-light;
margin-bottom: -.1rem;
} }
}
svg {
display: inline-block;
fill: $brand-grey-light;
margin-bottom: -0.1rem;
}
} }

View File

@ -5,21 +5,21 @@ import remarkReact from 'remark-react'
import styles from './Readme.module.scss' import styles from './Readme.module.scss'
export default function Readme({ object }) { export default function Readme({ object }) {
const readmeHtml = const readmeHtml =
object && remark().use(remarkReact).processSync(object.text).result object && remark().use(remarkReact).processSync(object.text).result
return ( return (
object && ( object && (
<aside className={styles.readme}> <aside className={styles.readme}>
<h3 className={styles.title}>README.md</h3> <h3 className={styles.title}>README.md</h3>
{readmeHtml} {readmeHtml}
</aside> </aside>
)
) )
)
} }
Readme.propTypes = { Readme.propTypes = {
object: PropTypes.shape({ object: PropTypes.shape({
text: PropTypes.string.isRequired text: PropTypes.string.isRequired
}) })
} }

View File

@ -1,30 +1,30 @@
@import 'variables'; @import 'variables';
.readme { .readme {
margin-top: $spacer / $line-height; margin-top: $spacer / $line-height;
padding: $spacer / 2; padding: $spacer / 2;
background: darken($brand-white, 2%); background: darken($brand-white, 2%);
h1, h1,
h2 { h2 {
font-size: $font-size-large; font-size: $font-size-large;
} }
h3, h3,
h4 { h4 {
font-size: $font-size-base; font-size: $font-size-base;
} }
img { img {
display: inline-block; display: inline-block;
} }
} }
.title { .title {
font-size: $font-size-small !important; // stylelint-disable-line font-size: $font-size-small !important; // stylelint-disable-line
font-family: $font-family-monospace; font-family: $font-family-monospace;
font-weight: $font-weight-base; font-weight: $font-weight-base;
margin: 0; margin: 0;
color: $brand-grey-light; color: $brand-grey-light;
margin-bottom: $spacer / 2; margin-bottom: $spacer / 2;
} }

View File

@ -5,36 +5,34 @@ import styles from './Title.module.scss'
import { ReactComponent as Forks } from '../../images/forks.svg' import { ReactComponent as Forks } from '../../images/forks.svg'
export default function Title({ name, isFork, parent, releases, url }) { export default function Title({ name, isFork, parent, releases, url }) {
return ( return (
<h1 className={styles.title}> <h1 className={styles.title}>
<a href={url}> <a href={url}>
{isFork && <Forks />} {isFork && <Forks />}
{name} {name}
{isFork && ( {isFork && (
<span className={styles.forkLine}> <span className={styles.forkLine}>{parent.nameWithOwner}</span>
{parent.nameWithOwner} )}
</span> </a>
)} {releases.edges[0] && (
</a> <a
{releases.edges[0] && ( href={`${url}/releases`}
<a className={styles.repositoryRelease}
href={`${url}/releases`} title="Latest release"
className={styles.repositoryRelease} >
title="Latest release" {releases.edges[0].node.tag.name}
> </a>
{releases.edges[0].node.tag.name} )}
</a> </h1>
)} )
</h1>
)
} }
Title.propTypes = { Title.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
isFork: PropTypes.bool, isFork: PropTypes.bool,
parent: PropTypes.shape({ parent: PropTypes.shape({
nameWithOwner: PropTypes.string nameWithOwner: PropTypes.string
}), }),
releases: PropTypes.object.isRequired, releases: PropTypes.object.isRequired,
url: PropTypes.string.isRequired url: PropTypes.string.isRequired
} }

View File

@ -1,53 +1,53 @@
@import 'variables'; @import 'variables';
.title { .title {
font-size: $font-size-h4; font-size: $font-size-h4;
margin-top: 0; margin-top: 0;
margin-bottom: $spacer / 2; margin-bottom: $spacer / 2;
border: 0; border: 0;
padding: 0; padding: 0;
width: 100%; width: 100%;
position: relative; position: relative;
a:first-of-type { a:first-of-type {
color: $brand-black; color: $brand-black;
&:hover,
&:focus {
color: $brand-pink;
}
}
svg {
width: 1em;
height: 1em;
display: inline-block;
fill: $brand-grey-light;
margin-right: $spacer / 8;
margin-left: -.2rem;
margin-bottom: -.2rem;
}
}
.repositoryRelease {
font-family: $font-family-base;
font-weight: $font-weight-base;
font-size: $font-size-small;
color: $brand-grey-light;
display: inline-block;
margin-left: $spacer / 4;
&:hover, &:hover,
&:focus { &:focus {
transform: none; color: $brand-pink;
} }
}
svg {
width: 1em;
height: 1em;
display: inline-block;
fill: $brand-grey-light;
margin-right: $spacer / 8;
margin-left: -0.2rem;
margin-bottom: -0.2rem;
}
}
.repositoryRelease {
font-family: $font-family-base;
font-weight: $font-weight-base;
font-size: $font-size-small;
color: $brand-grey-light;
display: inline-block;
margin-left: $spacer / 4;
&:hover,
&:focus {
transform: none;
}
} }
.forkLine { .forkLine {
display: inline; display: inline;
margin-left: $spacer / 4; margin-left: $spacer / 4;
font-size: $font-size-mini; font-size: $font-size-mini;
font-family: $font-family-monospace; font-family: $font-family-monospace;
font-weight: $font-weight-base; font-weight: $font-weight-base;
color: $brand-grey-light; color: $brand-grey-light;
} }

View File

@ -8,143 +8,142 @@ import Title from './Title'
import Links from './Links' import Links from './Links'
const queryGithub = graphql` const queryGithub = graphql`
query GitHubReposInfo { query GitHubReposInfo {
github { github {
organization(login: "oceanprotocol") { organization(login: "oceanprotocol") {
repositories(first: 100, privacy: PUBLIC) { repositories(first: 100, privacy: PUBLIC) {
edges { edges {
node { node {
name name
description description
url url
forkCount forkCount
isFork isFork
parent { parent {
nameWithOwner nameWithOwner
} }
stargazers { stargazers {
totalCount totalCount
} }
releases( releases(
first: 1 first: 1
orderBy: { field: CREATED_AT, direction: DESC } orderBy: { field: CREATED_AT, direction: DESC }
) { ) {
edges { edges {
node { node {
tag { tag {
name name
}
}
}
}
object(expression: "develop:README.md") {
id
... on GitHub_Blob {
text
}
}
}
} }
}
} }
} }
} object(expression: "develop:README.md") {
id
allRepositoriesYaml { ... on GitHub_Blob {
edges { text
node {
items {
name
links {
name
url
}
}
} }
}
} }
}
} }
}
} }
allRepositoriesYaml {
edges {
node {
items {
name
links {
name
url
}
}
}
}
}
}
` `
const Repository = ({ name, links, readme }) => ( const Repository = ({ name, links, readme }) => (
<StaticQuery <StaticQuery
query={queryGithub} query={queryGithub}
render={(data) => { render={(data) => {
const repositoriesGitHub = const repositoriesGitHub = data.github.organization.repositories.edges
data.github.organization.repositories.edges const repositoriesYaml = data.allRepositoriesYaml.edges
const repositoriesYaml = data.allRepositoriesYaml.edges
// just iterate over all repos until we have a name match, // just iterate over all repos until we have a name match,
// then return that repo, and then filter out all empty nodes // then return that repo, and then filter out all empty nodes
const repoFilteredArray = repositoriesGitHub const repoFilteredArray = repositoriesGitHub
.map(({ node }) => { .map(({ node }) => {
if (node.name === name) return node if (node.name === name) return node
}) })
.filter((n) => n) .filter((n) => n)
const repo = repoFilteredArray[0] const repo = repoFilteredArray[0]
// safeguard against more empty items, // safeguard against more empty items,
// e.g. when private repos are referenced in repositories.yml // e.g. when private repos are referenced in repositories.yml
if (repo === undefined) return null if (repo === undefined) return null
const { const {
url, url,
description, description,
forkCount, forkCount,
isFork, isFork,
parent, parent,
stargazers, stargazers,
releases, releases,
object object
} = repo } = repo
// enhance passed links array with what's in repositories.yml, // enhance passed links array with what's in repositories.yml,
// iterating over all repos until we have a name match // iterating over all repos until we have a name match
const linksFilteredArray = [] const linksFilteredArray = []
repositoriesYaml.map(({ node }) => { repositoriesYaml.map(({ node }) => {
node.items.forEach((item) => { node.items.forEach((item) => {
if (item.name === name) { if (item.name === name) {
linksFilteredArray.push(item.links) linksFilteredArray.push(item.links)
} }
}) })
}) })
const moreLinks = links || linksFilteredArray.filter((n) => n)[0] const moreLinks = links || linksFilteredArray.filter((n) => n)[0]
return ( return (
<article className={styles.repository}> <article className={styles.repository}>
<Title <Title
name={name} name={name}
releases={releases} releases={releases}
url={url} url={url}
isFork={isFork} isFork={isFork}
parent={parent} parent={parent}
/> />
<p>{!description ? '...' : description}</p> <p>{!description ? '...' : description}</p>
<footer className={styles.repositoryMeta}> <footer className={styles.repositoryMeta}>
<Links links={moreLinks} url={url} /> <Links links={moreLinks} url={url} />
<Numbers <Numbers
stargazers={stargazers} stargazers={stargazers}
forkCount={forkCount} forkCount={forkCount}
url={url} url={url}
name={name} name={name}
/> />
</footer> </footer>
{readme && <Readme object={object} />} {readme && <Readme object={object} />}
</article> </article>
) )
}} }}
/> />
) )
Repository.propTypes = { Repository.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
links: PropTypes.array, links: PropTypes.array,
readme: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]) readme: PropTypes.oneOfType([PropTypes.bool, PropTypes.string])
} }
export default Repository export default Repository

View File

@ -1,25 +1,25 @@
@import 'variables'; @import 'variables';
.repository { .repository {
padding: $spacer / $line-height; padding: $spacer / $line-height;
border: 1px solid $brand-grey-lighter; border: 1px solid $brand-grey-lighter;
background: $brand-white; background: $brand-white;
border-radius: $border-radius; border-radius: $border-radius;
font-size: $font-size-small; font-size: $font-size-small;
text-align: left; text-align: left;
width: 100%; width: 100%;
margin-bottom: $spacer; margin-bottom: $spacer;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
p { p {
align-self: flex-start; align-self: flex-start;
} }
} }
.repositoryMeta { .repositoryMeta {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
align-self: flex-end; align-self: flex-end;
width: 100%; width: 100%;
} }

View File

@ -3,83 +3,83 @@ import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
export default class TocScroll extends React.Component { export default class TocScroll extends React.Component {
static propTypes = { static propTypes = {
type: PropTypes.string, type: PropTypes.string,
element: PropTypes.string, element: PropTypes.string,
offset: PropTypes.number, offset: PropTypes.number,
timeout: PropTypes.number, timeout: PropTypes.number,
children: PropTypes.node.isRequired children: PropTypes.node.isRequired
}
componentDidMount() {
smoothscroll.polyfill()
}
handleClick = (e) => {
e.preventDefault()
let elem = 0
let scroll = true
const { type, element, offset, timeout } = this.props
if (type && element) {
switch (type) {
case 'class':
// eslint-disable-next-line prefer-destructuring
elem = document.getElementsByClassName(element)[0]
scroll = !!elem
break
case 'id':
elem = document.getElementById(element)
scroll = !!elem
break
default:
}
} }
componentDidMount() { if (scroll) {
smoothscroll.polyfill() this.scrollTo(elem, offset, timeout)
// update browser url
if (typeof window !== 'undefined') {
window.history.pushState({}, null, `#${element}`)
}
} else {
console.log(`Element not found: ${element}`) // eslint-disable-line
} }
}
handleClick = (e) => { scrollTo(element, offSet = 0, timeout = null) {
e.preventDefault() const elemPos = element
? element.getBoundingClientRect().top + window.pageYOffset
: 0
let elem = 0 if (timeout) {
let scroll = true setTimeout(() => {
const { type, element, offset, timeout } = this.props window.scroll({
top: elemPos + offSet,
if (type && element) { left: 0,
switch (type) { behavior: 'smooth'
case 'class': })
// eslint-disable-next-line prefer-destructuring }, timeout)
elem = document.getElementsByClassName(element)[0] } else {
scroll = !!elem window.scroll({
break top: elemPos + offSet,
case 'id': left: 0,
elem = document.getElementById(element) behavior: 'smooth'
scroll = !!elem })
break
default:
}
}
if (scroll) {
this.scrollTo(elem, offset, timeout)
// update browser url
if (typeof window !== 'undefined') {
window.history.pushState({}, null, `#${element}`)
}
} else {
console.log(`Element not found: ${element}`) // eslint-disable-line
}
} }
}
scrollTo(element, offSet = 0, timeout = null) { render() {
const elemPos = element return (
? element.getBoundingClientRect().top + window.pageYOffset <a
: 0 onClick={this.handleClick}
href={`#${this.props.element}`}
if (timeout) { {...this.props}
setTimeout(() => { >
window.scroll({ {this.props.children}
top: elemPos + offSet, </a>
left: 0, )
behavior: 'smooth' }
})
}, timeout)
} else {
window.scroll({
top: elemPos + offSet,
left: 0,
behavior: 'smooth'
})
}
}
render() {
return (
<a
onClick={this.handleClick}
href={`#${this.props.element}`}
{...this.props}
>
{this.props.children}
</a>
)
}
} }

View File

@ -4,171 +4,171 @@ import { StaticQuery, graphql } from 'gatsby'
import { Helmet } from 'react-helmet' import { Helmet } from 'react-helmet'
const query = graphql` const query = graphql`
query { query {
site { site {
siteMetadata { siteMetadata {
siteTitle siteTitle
siteDescription siteDescription
siteUrl siteUrl
} }
}
shareImage: allFile(filter: { name: { eq: "share" } }) {
edges {
node {
childImageSharp {
original {
src
}
}
}
}
}
} }
shareImage: allFile(filter: { name: { eq: "share" } }) {
edges {
node {
childImageSharp {
original {
src
}
}
}
}
}
}
` `
const createSchemaOrg = (title, description, image, url, siteMeta, article) => { const createSchemaOrg = (title, description, image, url, siteMeta, article) => {
const schemaOrgJSONLD = [ const schemaOrgJSONLD = [
{ {
'@context': 'http://schema.org', '@context': 'http://schema.org',
'@type': 'WebSite', '@type': 'WebSite',
url: siteMeta.siteUrl, url: siteMeta.siteUrl,
name: title name: title
}
]
if (article) {
schemaOrgJSONLD.push(
{
'@context': 'http://schema.org',
'@type': 'BreadcrumbList',
itemListElement: [
{
'@type': 'ListItem',
position: 1,
item: { '@id': url, name: title, image }
}
]
},
{
// https://schema.org/TechArticle
'@context': 'http://schema.org',
'@type': 'TechArticle',
name: title,
headline: title,
description,
url,
image: { '@type': 'URL', url: image }
}
)
} }
]
return schemaOrgJSONLD if (article) {
schemaOrgJSONLD.push(
{
'@context': 'http://schema.org',
'@type': 'BreadcrumbList',
itemListElement: [
{
'@type': 'ListItem',
position: 1,
item: { '@id': url, name: title, image }
}
]
},
{
// https://schema.org/TechArticle
'@context': 'http://schema.org',
'@type': 'TechArticle',
name: title,
headline: title,
description,
url,
image: { '@type': 'URL', url: image }
}
)
}
return schemaOrgJSONLD
} }
const MetaTags = ({ const MetaTags = ({
title, title,
description, description,
url, url,
image, image,
schema, schema,
siteMeta, siteMeta,
article, article,
location location
}) => ( }) => (
<Helmet <Helmet
defaultTitle={siteMeta.siteTitle} defaultTitle={siteMeta.siteTitle}
titleTemplate={`%s - ${siteMeta.siteTitle}`} titleTemplate={`%s - ${siteMeta.siteTitle}`}
> >
<html lang="en" /> <html lang="en" />
{title && <title>{title}</title>} {title && <title>{title}</title>}
{/* General tags */} {/* General tags */}
<meta name="description" content={description} /> <meta name="description" content={description} />
<meta name="image" content={image} /> <meta name="image" content={image} />
<link rel="canonical" href={url} /> <link rel="canonical" href={url} />
{/* Schema.org tags */} {/* Schema.org tags */}
<script type="application/ld+json">{schema}</script> <script type="application/ld+json">{schema}</script>
{/* OpenGraph tags */} {/* OpenGraph tags */}
<meta property="og:url" content={url} /> <meta property="og:url" content={url} />
{article && <meta property="og:type" content="article" />} {article && <meta property="og:type" content="article" />}
<meta property="og:title" content={title} /> <meta property="og:title" content={title} />
<meta property="og:description" content={description} /> <meta property="og:description" content={description} />
<meta property="og:image" content={image} /> <meta property="og:image" content={image} />
{/* Twitter Card tags */} {/* Twitter Card tags */}
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:creator" content="@oceanprotocol" /> <meta name="twitter:creator" content="@oceanprotocol" />
<meta name="twitter:title" content={title} /> <meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} /> <meta name="twitter:description" content={description} />
<meta name="twitter:image" content={image} /> <meta name="twitter:image" content={image} />
{/* Prevent search engine indexing except for live */} {/* Prevent search engine indexing except for live */}
{/* {location.hostname !== 'docs.oceanprotocol.com' && ( {/* {location.hostname !== 'docs.oceanprotocol.com' && (
<meta name="robots" content="noindex,nofollow" /> <meta name="robots" content="noindex,nofollow" />
)} */} )} */}
</Helmet> </Helmet>
) )
MetaTags.propTypes = { MetaTags.propTypes = {
title: PropTypes.string, title: PropTypes.string,
description: PropTypes.string, description: PropTypes.string,
url: PropTypes.string, url: PropTypes.string,
image: PropTypes.string, image: PropTypes.string,
schema: PropTypes.string, schema: PropTypes.string,
siteMeta: PropTypes.object, siteMeta: PropTypes.object,
article: PropTypes.bool, article: PropTypes.bool,
location: PropTypes.object.isRequired location: PropTypes.object.isRequired
} }
const Seo = ({ title, description, slug, article, location }) => ( const Seo = ({ title, description, slug, article, location }) => (
<StaticQuery <StaticQuery
query={query} query={query}
render={(data) => { render={(data) => {
const siteMeta = data.site.siteMetadata const siteMeta = data.site.siteMetadata
const shareImage = const shareImage =
data.shareImage.edges[0].node.childImageSharp.original.src data.shareImage.edges[0].node.childImageSharp.original.src
title = title || siteMeta.siteTitle title = title || siteMeta.siteTitle
description = description || siteMeta.siteDescription description = description || siteMeta.siteDescription
const url = siteMeta.siteUrl || siteMeta.siteUrl + slug const url = siteMeta.siteUrl || siteMeta.siteUrl + slug
const image = siteMeta.siteUrl + shareImage const image = siteMeta.siteUrl + shareImage
let schema = createSchemaOrg( let schema = createSchemaOrg(
title, title,
description, description,
image, image,
url, url,
siteMeta, siteMeta,
article article
) )
schema = JSON.stringify(schema) schema = JSON.stringify(schema)
return ( return (
<MetaTags <MetaTags
title={title} title={title}
description={description} description={description}
url={url} url={url}
image={image} image={image}
schema={schema} schema={schema}
siteMeta={siteMeta} siteMeta={siteMeta}
article={article} article={article}
location={location} location={location}
/> />
) )
}} }}
/> />
) )
Seo.propTypes = { Seo.propTypes = {
title: PropTypes.string, title: PropTypes.string,
description: PropTypes.string, description: PropTypes.string,
slug: PropTypes.string, slug: PropTypes.string,
article: PropTypes.bool, article: PropTypes.bool,
location: PropTypes.object.isRequired location: PropTypes.object.isRequired
} }
export default Seo export default Seo

View File

@ -5,153 +5,140 @@ import { ReactComponent as External } from '../images/external.svg'
import styles from './Sidebar.module.scss' import styles from './Sidebar.module.scss'
const SidebarLink = ({ link, title, linkClasses }) => { const SidebarLink = ({ link, title, linkClasses }) => {
if (link) { if (link) {
if (link.match(/^\s?http(s?)/gi)) { if (link.match(/^\s?http(s?)/gi)) {
return ( return (
<a <a
href={link} href={link}
className={linkClasses} className={linkClasses}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
{title} <External className={styles.external} /> {title} <External className={styles.external} />
</a> </a>
) )
} else {
return (
<Link to={link} className={linkClasses}>
{title}
</Link>
)
}
} else { } else {
return title return (
<Link to={link} className={linkClasses}>
{title}
</Link>
)
} }
} else {
return title
}
} }
SidebarLink.propTypes = { SidebarLink.propTypes = {
link: PropTypes.string.isRequired, link: PropTypes.string.isRequired,
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
linkClasses: PropTypes.string linkClasses: PropTypes.string
} }
const SidebarList = ({ items, location, toc, tocComponent }) => ( const SidebarList = ({ items, location, toc, tocComponent }) => (
<div className={styles.list}> <div className={styles.list}>
{toc ? ( {toc ? (
<div className={styles.toc}>{tocComponent}</div> <div className={styles.toc}>{tocComponent}</div>
) : ( ) : (
<ul> <ul>
{items.map((item, j) => ( {items.map((item, j) => (
<li key={j}> <li key={j}>
<SidebarLink <SidebarLink
link={item.link} link={item.link}
title={item.title} title={item.title}
linkClasses={ linkClasses={
item.link === location.pathname item.link === location.pathname ? styles.active : styles.link
? styles.active }
: styles.link />
} </li>
/> ))}
</li> </ul>
))} )}
</ul> </div>
)}
</div>
) )
SidebarList.propTypes = { SidebarList.propTypes = {
items: PropTypes.array.isRequired, items: PropTypes.array.isRequired,
location: PropTypes.object.isRequired, location: PropTypes.object.isRequired,
toc: PropTypes.bool, toc: PropTypes.bool,
tocComponent: PropTypes.object tocComponent: PropTypes.object
} }
const SidebarGroupTitle = ({ group }) => ( const SidebarGroupTitle = ({ group }) => (
<h4 className={styles.groupTitle}> <h4 className={styles.groupTitle}>
{group.items[0].link ? ( {group.items[0].link ? (
<SidebarLink <SidebarLink
link={group.items[0].link} link={group.items[0].link}
title={group.group} title={group.group}
linkClasses={styles.groupTitleLink} linkClasses={styles.groupTitleLink}
/> />
) : ( ) : (
group.group group.group
)} )}
</h4> </h4>
) )
SidebarGroupTitle.propTypes = { SidebarGroupTitle.propTypes = {
group: PropTypes.object.isRequired group: PropTypes.object.isRequired
} }
const SidebarGroup = ({ i, group, location, ...props }) => ( const SidebarGroup = ({ i, group, location, ...props }) => (
<> <>
<SidebarGroupTitle group={group} /> <SidebarGroupTitle group={group} />
<SidebarList <SidebarList key={i} items={group.items} location={location} {...props} />
key={i} </>
items={group.items}
location={location}
{...props}
/>
</>
) )
SidebarGroup.propTypes = { SidebarGroup.propTypes = {
i: PropTypes.number, i: PropTypes.number,
group: PropTypes.object, group: PropTypes.object,
location: PropTypes.object location: PropTypes.object
} }
export default class Sidebar extends Component { export default class Sidebar extends Component {
static propTypes = { static propTypes = {
sidebar: PropTypes.string, sidebar: PropTypes.string,
location: PropTypes.object.isRequired, location: PropTypes.object.isRequired,
collapsed: PropTypes.bool, collapsed: PropTypes.bool,
toc: PropTypes.bool, toc: PropTypes.bool,
tocComponent: PropTypes.element tocComponent: PropTypes.element
}
static defaultProps = { location: { pathname: '/' } }
render() {
const { sidebar, location, collapsed, toc, tocComponent } = this.props
if (sidebar) {
var sidebarfile = require(`../../data/sidebars/${sidebar}.yml`) // eslint-disable-line
} }
static defaultProps = { location: { pathname: '/' } } if (!sidebarfile) {
return null
render() {
const { sidebar, location, collapsed, toc, tocComponent } = this.props
if (sidebar) {
var sidebarfile = require(`../../data/sidebars/${sidebar}.yml`) // eslint-disable-line
}
if (!sidebarfile) {
return null
}
return (
<nav className={styles.sidebar}>
{sidebarfile.map((group, i) => (
<div key={i}>
{collapsed ? (
group.items.some(
(item) => item.link === location.pathname
) ? (
<SidebarGroup
i={i}
group={group}
location={location}
toc={toc}
tocComponent={tocComponent}
/>
) : (
<SidebarGroupTitle group={group} />
)
) : (
<SidebarGroup
i={i}
group={group}
location={location}
/>
)}
</div>
))}
</nav>
)
} }
return (
<nav className={styles.sidebar}>
{sidebarfile.map((group, i) => (
<div key={i}>
{collapsed ? (
group.items.some((item) => item.link === location.pathname) ? (
<SidebarGroup
i={i}
group={group}
location={location}
toc={toc}
tocComponent={tocComponent}
/>
) : (
<SidebarGroupTitle group={group} />
)
) : (
<SidebarGroup i={i} group={group} location={location} />
)}
</div>
))}
</nav>
)
}
} }

View File

@ -1,161 +1,161 @@
@import 'variables'; @import 'variables';
.sidebar { .sidebar {
padding-bottom: $spacer; padding-bottom: $spacer;
padding-right: $spacer / 2; padding-right: $spacer / 2;
position: sticky; position: sticky;
top: 0; top: 0;
max-height: 100vh; max-height: 100vh;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
&::-webkit-scrollbar, &::-webkit-scrollbar,
&::-moz-scrollbar { &::-moz-scrollbar {
display: none; display: none;
} }
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 8px; width: 8px;
height: 8px; height: 8px;
} }
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background: $brand-grey-lighter; background: $brand-grey-lighter;
} }
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
background: darken($brand-white, 3%); background: darken($brand-white, 3%);
} }
} }
.groupTitle { .groupTitle {
font-size: $font-size-small; font-size: $font-size-small;
font-family: $font-family-button; font-family: $font-family-button;
text-transform: uppercase; text-transform: uppercase;
margin-top: $spacer; margin-top: $spacer;
margin-bottom: $spacer / 4; margin-bottom: $spacer / 4;
} }
.groupTitleLink { .groupTitleLink {
color: $brand-grey-light; color: $brand-grey-light;
&:hover, &:hover,
&:focus { &:focus {
transform: none; transform: none;
color: $brand-grey-light; color: $brand-grey-light;
} }
} }
.list { .list {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
border-left: 1px solid $brand-grey-lighter; border-left: 1px solid $brand-grey-lighter;
margin-left: $spacer / 2; margin-left: $spacer / 2;
> ul { > ul {
padding-left: 0; padding-left: 0;
} }
li { li {
display: block; display: block;
&:before { &:before {
display: none; display: none;
}
} }
}
} }
.link, .link,
.toc a { .toc a {
color: $brand-grey; color: $brand-grey;
display: inline-block; display: inline-block;
padding: $spacer / 6 $spacer / 2; padding: $spacer / 6 $spacer / 2;
border-left: .1rem solid transparent; border-left: 0.1rem solid transparent;
margin-left: -.05rem; margin-left: -0.05rem;
&:hover, &:hover,
&:focus { &:focus {
transform: none; transform: none;
color: $brand-purple;
:global(.setup) & {
color: $brand-blue;
}
:global(.tutorials) & {
color: $orange;
}
:global(.references) & {
color: $green;
}
}
}
.toc {
ul {
padding-left: 0;
margin: 0;
ul {
border-left: 1px solid $brand-grey-lighter;
margin-left: $spacer;
font-size: $font-size-small;
}
}
li {
margin: 0;
}
a {
padding-top: $spacer / 12;
padding-bottom: $spacer / 12;
}
code {
background: none;
color: inherit;
}
[data-deprecated='true'] code {
opacity: .5;
}
}
.active {
composes: link;
color: $brand-purple; color: $brand-purple;
border-left-color: $brand-purple;
:global(.setup) & { :global(.setup) & {
color: $brand-blue; color: $brand-blue;
border-left-color: $brand-blue;
} }
:global(.tutorials) & { :global(.tutorials) & {
color: $orange; color: $orange;
border-left-color: $orange;
} }
:global(.references) & { :global(.references) & {
color: $green; color: $green;
border-left-color: $green;
} }
}
}
.toc {
ul {
padding-left: 0;
margin: 0;
ul {
border-left: 1px solid $brand-grey-lighter;
margin-left: $spacer;
font-size: $font-size-small;
}
}
li {
margin: 0;
}
a {
padding-top: $spacer / 12;
padding-bottom: $spacer / 12;
}
code {
background: none;
color: inherit;
}
[data-deprecated='true'] code {
opacity: 0.5;
}
}
.active {
composes: link;
color: $brand-purple;
border-left-color: $brand-purple;
:global(.setup) & {
color: $brand-blue;
border-left-color: $brand-blue;
}
:global(.tutorials) & {
color: $orange;
border-left-color: $orange;
}
:global(.references) & {
color: $green;
border-left-color: $green;
}
} }
.scrollspyActive { .scrollspyActive {
> a { > a {
color: $green; color: $green;
border-left-color: $green; border-left-color: $green;
} }
} }
.external { .external {
fill: $brand-grey-light; fill: $brand-grey-light;
display: inline-block; display: inline-block;
width: $font-size-mini; width: $font-size-mini;
height: $font-size-mini; height: $font-size-mini;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -17,63 +17,56 @@ const giphyClient = giphyAPI('LfXRwufRyt6PK414G2kKJBv3L8NdnxyR')
const tag = 'ocean' const tag = 'ocean'
export default class NotFoundPage extends Component { export default class NotFoundPage extends Component {
state = { gif: '' } state = { gif: '' }
static propTypes = { static propTypes = {
location: PropTypes.object location: PropTypes.object
}
componentDidMount() {
this.getRandomGif()
}
async getRandomGif() {
try {
const response = await giphyClient.random('gifs', { tag })
const gif = response.data.images.original.mp4
this.setState({ gif })
} catch (error) {
return error
} }
}
componentDidMount() { handleClick = (e) => {
this.getRandomGif() e.preventDefault()
} this.getRandomGif()
}
async getRandomGif() { render() {
try { return (
const response = await giphyClient.random('gifs', { tag }) <>
const gif = response.data.images.original.mp4 <Seo location={this.props.location} title="404 - Not Found" />
this.setState({ gif }) <Layout location={this.props.location}>
} catch (error) { <Content>
return error <article className={styles.content}>
} <h1>Page not found.</h1>
} <p>
You just hit a route that doesn&#39;t exist... the sadness.
Check your url, <Link to="/">go back to the homepage</Link>, or
check out some <em>{tag}</em> gifs, entirely your choice.
</p>
handleClick = (e) => { <video className="gif" src={this.state.gif} autoPlay loop />
e.preventDefault()
this.getRandomGif()
}
render() { <div>
return ( <button
<> onClick={this.handleClick}
<Seo location={this.props.location} title="404 - Not Found" /> >{`Get another ${tag} gif`}</button>
<Layout location={this.props.location}> </div>
<Content> </article>
<article className={styles.content}> </Content>
<h1>Page not found.</h1> </Layout>
<p> </>
You just hit a route that doesn&#39;t exist... )
the sadness. Check your url,{' '} }
<Link to="/">go back to the homepage</Link>, or
check out some <em>{tag}</em> gifs, entirely
your choice.
</p>
<video
className="gif"
src={this.state.gif}
autoPlay
loop
/>
<div>
<button
onClick={this.handleClick}
>{`Get another ${tag} gif`}</button>
</div>
</article>
</Content>
</Layout>
</>
)
}
} }

View File

@ -1,28 +1,28 @@
@import 'variables'; @import 'variables';
.content { .content {
max-width: 33rem; max-width: 33rem;
margin: auto; margin: auto;
text-align: center; text-align: center;
video { video {
margin-top: $spacer; margin-top: $spacer;
margin-bottom: $spacer; margin-bottom: $spacer;
display: block; display: block;
width: auto; width: auto;
max-height: 300px; max-height: 300px;
border: $page-frame solid $brand-black; border: $page-frame solid $brand-black;
background: $brand-black; background: $brand-black;
} }
button { button {
background: none; background: none;
border: 0; border: 0;
box-shadow: none; box-shadow: none;
font-family: $font-family-button; font-family: $font-family-button;
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
font-size: $font-size-base; font-size: $font-size-base;
color: $brand-pink; color: $brand-pink;
cursor: pointer; cursor: pointer;
} }
} }

View File

@ -12,100 +12,96 @@ import { ReactComponent as Arrow } from '../images/arrow.svg'
import styles from './index.module.scss' import styles from './index.module.scss'
const SectionBox = ({ to, children, ...props }) => const SectionBox = ({ to, children, ...props }) =>
to ? ( to ? (
<Link to={to} {...props}> <Link to={to} {...props}>
{children} {children}
</Link> </Link>
) : ( ) : (
<div {...props}>{children}</div> <div {...props}>{children}</div>
) )
SectionBox.propTypes = { SectionBox.propTypes = {
to: PropTypes.string.isRequired, to: PropTypes.string.isRequired,
children: PropTypes.any.isRequired children: PropTypes.any.isRequired
} }
const SectionLink = ({ to, title, color, children }) => { const SectionLink = ({ to, title, color, children }) => {
// eslint-disable-next-line // eslint-disable-next-line
let classNames = classnames(styles.link, { let classNames = classnames(styles.link, {
[styles.purple]: color === 'purple', [styles.purple]: color === 'purple',
[styles.blue]: color === 'blue', [styles.blue]: color === 'blue',
[styles.orange]: color === 'orange', [styles.orange]: color === 'orange',
[styles.green]: color === 'green' [styles.green]: color === 'green'
}) })
return ( return (
<SectionBox to={to} className={classNames}> <SectionBox to={to} className={classNames}>
<h3 className={styles.sectionTitle}>{title}</h3> <h3 className={styles.sectionTitle}>{title}</h3>
<p className={styles.sectionText}>{children}</p> <p className={styles.sectionText}>{children}</p>
{title !== 'API References' && ( {title !== 'API References' && (
<span className={styles.sectionMore}> <span className={styles.sectionMore}>
Learn More <Arrow /> Learn More <Arrow />
</span> </span>
)} )}
</SectionBox> </SectionBox>
) )
} }
SectionLink.propTypes = { SectionLink.propTypes = {
to: PropTypes.string.isRequired, to: PropTypes.string.isRequired,
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
color: PropTypes.string, color: PropTypes.string,
children: PropTypes.any children: PropTypes.any
} }
const IndexPage = ({ data, location }) => ( const IndexPage = ({ data, location }) => (
<> <>
<Seo location={location} /> <Seo location={location} />
<Layout location={location} header={<HeaderHome />}> <Layout location={location} header={<HeaderHome />}>
<Content> <Content>
<ul className={styles.sections}> <ul className={styles.sections}>
{data.allSectionsYaml.edges.map(({ node }) => ( {data.allSectionsYaml.edges.map(({ node }) => (
<li key={node.title} className={styles.section}> <li key={node.title} className={styles.section}>
<SectionLink <SectionLink to={node.link} title={node.title} color={node.color}>
to={node.link} {node.description}
title={node.title} </SectionLink>
color={node.color} </li>
> ))}
{node.description} </ul>
</SectionLink>
</li>
))}
</ul>
<QuickRun /> <QuickRun />
<Repositories /> <Repositories />
</Content> </Content>
</Layout> </Layout>
</> </>
) )
IndexPage.propTypes = { IndexPage.propTypes = {
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
location: PropTypes.object.isRequired location: PropTypes.object.isRequired
} }
export default IndexPage export default IndexPage
export const IndexQuery = graphql` export const IndexQuery = graphql`
query { query {
site { site {
siteMetadata { siteMetadata {
siteDescription siteDescription
} }
}
allSectionsYaml {
edges {
node {
title
description
link
color
}
}
}
} }
allSectionsYaml {
edges {
node {
title
description
link
color
}
}
}
}
` `

View File

@ -2,118 +2,118 @@
@import 'animations'; @import 'animations';
.sections { .sections {
list-style: none; list-style: none;
padding: 0; padding: 0;
margin: 0; margin: 0;
margin-top: -($spacer * 4); margin-top: -($spacer * 4);
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
} }
} }
.section { .section {
margin-top: $spacer; margin-top: $spacer;
animation: fadeInUp .6s ease-out backwards; animation: fadeInUp 0.6s ease-out backwards;
&:before { &:before {
display: none; display: none;
} }
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
flex: 0 0 31%; flex: 0 0 31%;
} }
animation-delay: .4s; animation-delay: 0.4s;
&:nth-child(2) { &:nth-child(2) {
animation-delay: .6s; animation-delay: 0.6s;
} }
&:nth-child(3) { &:nth-child(3) {
animation-delay: .8s; animation-delay: 0.8s;
} }
&:last-child { &:last-child {
flex-basis: 100%; flex-basis: 100%;
text-align: center; text-align: center;
} }
} }
.link { .link {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
padding: $spacer $spacer * $line-height; padding: $spacer $spacer * $line-height;
border-radius: $border-radius; border-radius: $border-radius;
box-shadow: rgba($brand-black, .1) 0 9px 18px; box-shadow: rgba($brand-black, 0.1) 0 9px 18px;
color: $brand-grey; color: $brand-grey;
background: $brand-white; background: $brand-white;
height: 100%; height: 100%;
&:hover, &:hover,
&:focus { &:focus {
box-shadow: rgba($brand-black, .1) 0 12px 20px; box-shadow: rgba($brand-black, 0.1) 0 12px 20px;
svg { svg {
transform: translate3d(.2rem, 0, 0); transform: translate3d(0.2rem, 0, 0);
}
} }
}
} }
.purple { .purple {
.sectionTitle, .sectionTitle,
.sectionMore { .sectionMore {
color: $brand-purple; color: $brand-purple;
} }
} }
.blue { .blue {
.sectionTitle, .sectionTitle,
.sectionMore { .sectionMore {
color: $brand-blue; color: $brand-blue;
} }
} }
.orange { .orange {
.sectionTitle, .sectionTitle,
.sectionMore { .sectionMore {
color: $orange; color: $orange;
} }
} }
.green { .green {
.sectionTitle, .sectionTitle,
.sectionMore { .sectionMore {
color: $green; color: $green;
} }
} }
.sectionTitle { .sectionTitle {
margin-top: 0; margin-top: 0;
margin-bottom: $spacer / $line-height; margin-bottom: $spacer / $line-height;
width: 100%; width: 100%;
} }
.sectionText { .sectionText {
margin-bottom: 0; margin-bottom: 0;
color: $brand-grey; color: $brand-grey;
width: 100%; width: 100%;
} }
.sectionMore { .sectionMore {
align-self: flex-end; align-self: flex-end;
margin-top: $spacer / $line-height; margin-top: $spacer / $line-height;
color: $brand-pink; color: $brand-pink;
width: 100%; width: 100%;
font-family: $font-family-button; font-family: $font-family-button;
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
svg { svg {
display: inline-block; display: inline-block;
width: $font-size-small; width: $font-size-small;
height: $font-size-small; height: $font-size-small;
fill: $brand-grey-light; fill: $brand-grey-light;
transition: transform .2s ease-out; transition: transform 0.2s ease-out;
} }
} }

View File

@ -1,21 +1,21 @@
@keyframes fadeInUp { @keyframes fadeInUp {
0% { 0% {
opacity: .01; opacity: 0.01;
transform: translate3d(0, 5rem, 0); transform: translate3d(0, 5rem, 0);
} }
100% { 100% {
opacity: 1; opacity: 1;
transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0);
} }
} }
@keyframes fadeIn { @keyframes fadeIn {
0% { 0% {
opacity: .01; opacity: 0.01;
} }
100% { 100% {
opacity: 1; opacity: 1;
} }
} }

View File

@ -6,150 +6,150 @@ code,
kbd, kbd,
pre, pre,
samp { samp {
font-family: $font-family-monospace; font-family: $font-family-monospace;
font-size: $font-size-small; font-size: $font-size-small;
border-radius: $border-radius; border-radius: $border-radius;
background: lighten($brand-grey-light, 35%); background: lighten($brand-grey-light, 35%);
color: $brand-grey; color: $brand-grey;
text-shadow: none; text-shadow: none;
h1 &, h1 &,
h2 &, h2 &,
h3 &, h3 &,
h4 &, h4 &,
h5 & { h5 & {
font-size: inherit; font-size: inherit;
} }
} }
:not(pre) > code { :not(pre) > code {
display: inline-block; display: inline-block;
padding-left: .3rem; padding-left: 0.3rem;
padding-right: .3rem; padding-right: 0.3rem;
} }
a > code { a > code {
color: $brand-pink; color: $brand-pink;
} }
pre { pre {
display: block;
margin: $spacer / 2 0;
padding: 0;
position: relative;
background: lighten($brand-grey-light, 35%) !important;
// make 'em scrollable
overflow: auto;
-webkit-overflow-scrolling: touch;
max-height: 800px;
width: 100%;
code {
background: none;
padding: $spacer / 1.5;
white-space: pre;
display: block; display: block;
margin: $spacer / 2 0; color: $brand-grey;
padding: 0; overflow-wrap: normal;
position: relative; word-wrap: normal;
background: lighten($brand-grey-light, 35%) !important; word-break: normal;
float: left;
// make 'em scrollable
overflow: auto;
-webkit-overflow-scrolling: touch;
max-height: 800px;
width: 100%; width: 100%;
}
code {
background: none;
padding: $spacer / 1.5;
white-space: pre;
display: block;
color: $brand-grey;
overflow-wrap: normal;
word-wrap: normal;
word-break: normal;
float: left;
width: 100%;
}
} }
pre[data-language]:before { pre[data-language]:before {
background: $brand-grey-lighter; background: $brand-grey-lighter;
border-radius: 0 0 $border-radius $border-radius; border-radius: 0 0 $border-radius $border-radius;
color: $brand-grey; color: $brand-grey;
font-size: $font-size-mini; font-size: $font-size-mini;
font-family: $font-family-monospace; font-family: $font-family-monospace;
letter-spacing: .05em; letter-spacing: 0.05em;
line-height: 1; line-height: 1;
padding: .25rem .5rem; padding: 0.25rem 0.5rem;
position: absolute; position: absolute;
right: $spacer / 2; right: $spacer / 2;
top: 0; top: 0;
} }
pre[data-language='js']:before { pre[data-language='js']:before {
content: 'js'; content: 'js';
} }
pre[data-language='jsx']:before { pre[data-language='jsx']:before {
content: 'jsx'; content: 'jsx';
} }
pre[data-language='bash'] { pre[data-language='bash'] {
&:before {
content: 'bash';
}
.vscode-highlight-line:only-child {
padding-left: 0.5rem;
display: block;
&:before { &:before {
content: 'bash'; content: '$';
} opacity: 0.5;
display: inline-block;
.vscode-highlight-line:only-child { margin-left: -0.5rem;
padding-left: .5rem; margin-right: 0.5rem;
display: block;
&:before {
content: '$';
opacity: .5;
display: inline-block;
margin-left: -.5rem;
margin-right: .5rem;
}
} }
}
} }
pre[data-language='html']:before { pre[data-language='html']:before {
content: 'html'; content: 'html';
} }
pre[data-language='css']:before { pre[data-language='css']:before {
content: 'css'; content: 'css';
} }
pre[data-language='php']:before { pre[data-language='php']:before {
content: 'php'; content: 'php';
} }
pre[data-language='python']:before { pre[data-language='python']:before {
content: 'python'; content: 'python';
} }
pre[data-language='java']:before { pre[data-language='java']:before {
content: 'java'; content: 'java';
} }
pre[data-language='markdown']:before { pre[data-language='markdown']:before {
content: 'markdown'; content: 'markdown';
} }
pre[data-language='toml']:before { pre[data-language='toml']:before {
content: 'toml'; content: 'toml';
} }
.gatsby-code-title { .gatsby-code-title {
background: lighten($brand-grey-light, 35%); background: lighten($brand-grey-light, 35%);
padding: $spacer / 4 $spacer / 2; padding: $spacer / 4 $spacer / 2;
margin-bottom: -($spacer / 2); margin-bottom: -($spacer / 2);
border-bottom: 1px solid $brand-white; border-bottom: 1px solid $brand-white;
font-family: $font-family-monospace; font-family: $font-family-monospace;
color: $brand-grey-light; color: $brand-grey-light;
font-size: $font-size-small; font-size: $font-size-small;
border-top-left-radius: $border-radius; border-top-left-radius: $border-radius;
border-top-right-radius: $border-radius; border-top-right-radius: $border-radius;
} }
.vscode-highlight-line { .vscode-highlight-line {
display: inline-block; display: inline-block;
&.vscode-highlight-line-highlighted { &.vscode-highlight-line-highlighted {
background-color: lighten($brand-grey-light, 30%); background-color: lighten($brand-grey-light, 30%);
margin-left: -($spacer / 1.5); margin-left: -($spacer / 1.5);
margin-right: -($spacer / 1.5); margin-right: -($spacer / 1.5);
padding-left: $spacer / 1.85; padding-left: $spacer / 1.85;
padding-right: $spacer / 1.5; padding-right: $spacer / 1.5;
border-left: .25rem solid $brand-grey-light; border-left: 0.25rem solid $brand-grey-light;
width: calc(100% + #{$spacer * 1.5}); width: calc(100% + #{$spacer * 1.5});
} }
} }

View File

@ -1,26 +1,26 @@
@font-face { @font-face {
font-family: 'Sharp Sans Display'; font-family: 'Sharp Sans Display';
src: url('../fonts/SharpSansDispNo1-Bold.woff2') format('woff2'), src: url('../fonts/SharpSansDispNo1-Bold.woff2') format('woff2'),
url('../fonts/SharpSansDispNo1-Bold.woff') format('woff'); url('../fonts/SharpSansDispNo1-Bold.woff') format('woff');
font-weight: 600; font-weight: 600;
font-style: normal; font-style: normal;
font-stretch: normal; font-stretch: normal;
} }
@font-face { @font-face {
font-family: 'Sharp Sans Medium'; font-family: 'Sharp Sans Medium';
src: url('../fonts/SharpSans-Medium.woff2') format('woff2'), src: url('../fonts/SharpSans-Medium.woff2') format('woff2'),
url('../fonts/SharpSans-Medium.woff') format('woff'); url('../fonts/SharpSans-Medium.woff') format('woff');
font-weight: 500; font-weight: 500;
font-style: normal; font-style: normal;
font-stretch: normal; font-stretch: normal;
} }
@font-face { @font-face {
font-family: 'Sharp Sans Bold'; font-family: 'Sharp Sans Bold';
src: url('../fonts/SharpSans-Bold.woff2') format('woff2'), src: url('../fonts/SharpSans-Bold.woff2') format('woff2'),
url('../fonts/SharpSans-Bold.woff') format('woff'); url('../fonts/SharpSans-Bold.woff') format('woff');
font-weight: 600; font-weight: 600;
font-style: normal; font-style: normal;
font-stretch: normal; font-stretch: normal;
} }

View File

@ -10,6 +10,7 @@ $brand-grey: #41474e;
$brand-grey-light: #8b98a9; $brand-grey-light: #8b98a9;
$brand-grey-dark: #303030; $brand-grey-dark: #303030;
$brand-grey-lighter: #e2e2e2; $brand-grey-lighter: #e2e2e2;
$brand-grey-dimmed: #f7f7f7;
$green: #5fb359; $green: #5fb359;
$red: #d80606; $red: #d80606;
@ -23,20 +24,20 @@ $body-background: darken($brand-white, 1%);
// Fonts // Fonts
// stylelint-disable value-keyword-case // stylelint-disable value-keyword-case
$font-family-base: 'Sharp Sans Medium', -apple-system, blinkmacsystemfont, $font-family-base: 'Sharp Sans Medium', -apple-system, blinkmacsystemfont,
'Segoe UI', helvetica, arial, sans-serif; 'Segoe UI', helvetica, arial, sans-serif;
$font-family-title: 'Sharp Sans Display', -apple-system, blinkmacsystemfont, $font-family-title: 'Sharp Sans Display', -apple-system, blinkmacsystemfont,
'Segoe UI', helvetica, arial, sans-serif; 'Segoe UI', helvetica, arial, sans-serif;
$font-family-button: 'Sharp Sans Bold', -apple-system, blinkmacsystemfont, $font-family-button: 'Sharp Sans Bold', -apple-system, blinkmacsystemfont,
'Segoe UI', helvetica, arial, sans-serif; 'Segoe UI', helvetica, arial, sans-serif;
$font-family-monospace: 'Fira Code', 'Fira Mono', menlo, monaco, consolas, $font-family-monospace: 'Fira Code', 'Fira Mono', menlo, monaco, consolas,
'Courier New', monospace; 'Courier New', monospace;
// stylelint-enable value-keyword-case // stylelint-enable value-keyword-case
$font-size-root: 15px; $font-size-root: 15px;
$font-size-base: 1rem; $font-size-base: 1rem;
$font-size-large: 1.2rem; $font-size-large: 1.2rem;
$font-size-small: .85rem; $font-size-small: 0.85rem;
$font-size-mini: .65rem; $font-size-mini: 0.65rem;
$font-size-text: $font-size-base; $font-size-text: $font-size-base;
$font-size-label: $font-size-base; $font-size-label: $font-size-base;
$font-size-title: 1.4rem; $font-size-title: 1.4rem;
@ -53,7 +54,7 @@ $line-height: 1.6;
// Sizes // Sizes
$spacer: 2rem; $spacer: 2rem;
$page-frame: .75rem; $page-frame: 0.75rem;
$break-point--small: 640px; $break-point--small: 640px;
$break-point--medium: 860px; $break-point--medium: 860px;
@ -61,6 +62,6 @@ $break-point--large: 1140px;
$break-point--huge: 1400px; $break-point--huge: 1400px;
$brand-border-width: 1px; $brand-border-width: 1px;
$border-radius: .2rem; $border-radius: 0.2rem;
$narrowWidth: 35rem; $narrowWidth: 35rem;

View File

@ -6,113 +6,109 @@
*, *,
*:before, *:before,
*:after { *:after {
box-sizing: border-box; box-sizing: border-box;
} }
html { html {
font-size: $font-size-root; font-size: $font-size-root;
} }
body { body {
color: $brand-black; color: $brand-black;
font-size: $font-size-base; font-size: $font-size-base;
font-family: $font-family-base; font-family: $font-family-base;
font-weight: $font-weight-base; font-weight: $font-weight-base;
line-height: $line-height; line-height: $line-height;
background: $body-background; background: $body-background;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
position: relative; position: relative;
margin: 0; margin: 0;
@media screen and (min-width: $break-point--small) {
padding: $page-frame;
}
} }
a { a {
text-decoration: none;
color: $brand-pink;
transition: 0.2s ease-out;
&:hover,
&:focus {
color: darken($brand-pink, 15%);
text-decoration: none; text-decoration: none;
color: $brand-pink; transform: translate3d(0, -0.1rem, 0);
transition: .2s ease-out; }
&:hover, &:active {
&:focus { color: darken($brand-pink, 15%);
color: darken($brand-pink, 15%); text-decoration: none;
text-decoration: none; transform: none;
transform: translate3d(0, -.1rem, 0); transition: none;
} }
&:active {
color: darken($brand-pink, 15%);
text-decoration: none;
transform: none;
transition: none;
}
} }
p { p {
margin: 0; margin: 0;
margin-bottom: $spacer / $line-height; margin-bottom: $spacer / $line-height;
} }
// Lists // Lists
///////////////////////////////////// /////////////////////////////////////
ul { ul {
li { li {
&:before { &:before {
content: ' \25AA'; // Black Small Square: &#9642; content: ' \25AA'; // Black Small Square: &#9642;
top: -2px; top: -2px;
}
} }
}
} }
ol { ol {
counter-reset: ol-counter; counter-reset: ol-counter;
li { li {
&:before { &:before {
content: counter(ol-counter) '.'; content: counter(ol-counter) '.';
counter-increment: ol-counter; counter-increment: ol-counter;
font-family: $font-family-button; font-family: $font-family-button;
}
} }
}
ul li:before { ul li:before {
content: ' \25AA'; content: ' \25AA';
} }
} }
ul, ul,
ol { ol {
margin-top: 0; margin-top: 0;
margin-bottom: $spacer; margin-bottom: $spacer;
padding-left: $spacer / $line-height; padding-left: $spacer / $line-height;
list-style: none; list-style: none;
li { li {
position: relative; position: relative;
display: block; display: block;
&:before { &:before {
position: absolute; position: absolute;
left: -($spacer / $line-height); left: -($spacer / $line-height);
color: $brand-grey-light; color: $brand-grey-light;
user-select: none; user-select: none;
}
+ li {
margin-top: $spacer / 3;
}
ul,
ol,
p {
margin-bottom: 0;
margin-top: $spacer / 3;
}
} }
+ li {
margin-top: $spacer / 3;
}
ul,
ol,
p {
margin-bottom: 0;
margin-top: $spacer / 3;
}
}
} }
// Inline typography // Inline typography
@ -121,23 +117,23 @@ ol {
b, b,
strong, strong,
.bold { .bold {
font-family: $font-family-button; font-family: $font-family-button;
font-weight: 600; font-weight: 600;
} }
em, em,
.italic { .italic {
font-style: italic; font-style: italic;
} }
abbr[title], abbr[title],
dfn { dfn {
text-transform: none; text-transform: none;
font-style: normal; font-style: normal;
font-size: inherit; font-size: inherit;
border-bottom: 1px dashed $brand-grey-light; border-bottom: 1px dashed $brand-grey-light;
cursor: help; cursor: help;
font-feature-settings: inherit; font-feature-settings: inherit;
} }
h1, h1,
@ -145,30 +141,30 @@ h2,
h3, h3,
h4, h4,
h5 { h5 {
font-family: $font-family-title; font-family: $font-family-title;
color: inherit; color: inherit;
line-height: 1.2; line-height: 1.2;
font-weight: 600; font-weight: 600;
} }
h1 { h1 {
font-size: $font-size-h1; font-size: $font-size-h1;
} }
h2 { h2 {
font-size: $font-size-h2; font-size: $font-size-h2;
} }
h3 { h3 {
font-size: $font-size-h3; font-size: $font-size-h3;
} }
h4 { h4 {
font-size: $font-size-h4; font-size: $font-size-h4;
} }
h5 { h5 {
font-size: $font-size-h5; font-size: $font-size-h5;
} }
// Responsive Media // Responsive Media
@ -182,102 +178,102 @@ audio,
embed, embed,
canvas, canvas,
picture { picture {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
margin: 0 auto; margin: 0 auto;
display: block; display: block;
} }
hr { hr {
margin: $spacer 0; margin: $spacer 0;
border: 0; border: 0;
border-bottom: .1rem solid $brand-grey-lighter; border-bottom: 0.1rem solid $brand-grey-lighter;
} }
// Quotes // Quotes
///////////////////////////////////// /////////////////////////////////////
q { q {
font-style: italic; font-style: italic;
} }
cite { cite {
font-style: normal; font-style: normal;
text-transform: uppercase; text-transform: uppercase;
} }
blockquote, blockquote,
blockquote > p { blockquote > p {
font-style: italic; font-style: italic;
color: lighten($brand-grey, 15%); color: lighten($brand-grey, 15%);
} }
blockquote { blockquote {
margin: 0 0 $spacer; margin: 0 0 $spacer;
padding-left: $spacer / 2; padding-left: $spacer / 2;
border-left: .2rem solid $brand-grey-lighter; border-left: 0.2rem solid $brand-grey-lighter;
@media screen and (min-width: $break-point--small) { @media screen and (min-width: $break-point--small) {
padding-left: $spacer / $line-height; padding-left: $spacer / $line-height;
} }
} }
// Tables // Tables
///////////////////////////////////// /////////////////////////////////////
table { table {
width: 100%; width: 100%;
margin-bottom: $spacer * $line-height; margin-bottom: $spacer * $line-height;
border-collapse: collapse; border-collapse: collapse;
display: block; display: block;
// make 'em scrollable // make 'em scrollable
overflow: auto; overflow: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
th, th,
td { td {
border: 0; border: 0;
margin: 0; margin: 0;
padding: $spacer / 2; padding: $spacer / 2;
border-bottom: 1px solid $brand-grey-lighter; border-bottom: 1px solid $brand-grey-lighter;
text-align: left; text-align: left;
font-size: 90%; font-size: 90%;
vertical-align: top; vertical-align: top;
&[align='center'] { &[align='center'] {
text-align: center; text-align: center;
}
&[align='right'] {
text-align: right;
}
} }
th { &[align='right'] {
font-family: $font-family-button; text-align: right;
font-weight: 600;
} }
}
th {
font-family: $font-family-button;
font-weight: 600;
}
} }
// Selection // Selection
///////////////////////////////////// /////////////////////////////////////
::-moz-selection { ::-moz-selection {
background: $brand-grey-light; background: $brand-grey-light;
color: #fff; color: #fff;
} }
::selection { ::selection {
background: $brand-grey-light; background: $brand-grey-light;
color: #fff; color: #fff;
} }
// Gatsby specific // Gatsby specific
///////////////////////////////////// /////////////////////////////////////
.anchor { .anchor {
margin-top: .6rem; margin-top: 0.6rem;
} }
@import 'code'; @import 'code';

View File

@ -14,147 +14,141 @@ import Seo from '../components/Seo'
import styles from './Doc.module.scss' import styles from './Doc.module.scss'
const DocMain = ({ title, description, tableOfContents, post, single }) => ( const DocMain = ({ title, description, tableOfContents, post, single }) => (
<article className={single ? styles.mainSingle : styles.main}> <article className={single ? styles.mainSingle : styles.main}>
<DocHeader title={title} description={description} /> <DocHeader title={title} description={description} />
{tableOfContents && <DocToc tableOfContents={tableOfContents} />} {tableOfContents && <DocToc tableOfContents={tableOfContents} />}
<DocContent html={post.html} htmlAst={post.htmlAst} /> <DocContent html={post.html} htmlAst={post.htmlAst} />
<DocFooter post={post} /> <DocFooter post={post} />
</article> </article>
) )
DocMain.propTypes = { DocMain.propTypes = {
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
description: PropTypes.string, description: PropTypes.string,
tableOfContents: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), tableOfContents: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
post: PropTypes.object.isRequired, post: PropTypes.object.isRequired,
single: PropTypes.bool single: PropTypes.bool
} }
export default class DocTemplate extends Component { export default class DocTemplate extends Component {
static propTypes = { static propTypes = {
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
location: PropTypes.object.isRequired location: PropTypes.object.isRequired
}
// output section title as defined in sections.yml
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => {
// compare section against section title from sections.yml
if (
node.title
.toLowerCase()
.includes(this.props.data.markdownRemark.fields.section)
) {
return node.title
} }
})
// output section title as defined in sections.yml render() {
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => { const { location } = this.props
// compare section against section title from sections.yml const post = this.props.data.markdownRemark
if ( const { section, slug } = post.fields
node.title const { title, description } = post.frontmatter
.toLowerCase() const { tableOfContents } = post
.includes(this.props.data.markdownRemark.fields.section)
) {
return node.title
}
})
render() { const isApiSection = location.pathname.includes('/references/')
const { location } = this.props
const post = this.props.data.markdownRemark
const { section, slug } = post.fields
const { title, description } = post.frontmatter
const { tableOfContents } = post
const isApiSection = location.pathname.includes('/references/') return (
<>
<Helmet>
<body className={section} />
</Helmet>
return ( <Seo
<> title={title}
<Helmet> description={description}
<body className={section} /> slug={slug}
</Helmet> article
location={location}
/>
<Seo <Layout location={location}>
title={title} <HeaderSection title={section ? this.sectionTitle : title} />
description={description}
slug={slug} <Content>
article {section ? (
<main className={styles.wrapper}>
<aside className={styles.sidebar}>
<Sidebar
location={location} location={location}
sidebar={section}
collapsed={isApiSection}
toc={
isApiSection &&
!location.pathname.includes('/references/introduction/')
}
tableOfContents={tableOfContents}
/>
</aside>
<DocMain
title={title}
description={description}
tableOfContents={!isApiSection && tableOfContents}
post={post}
/> />
</main>
<Layout location={location}> ) : (
<HeaderSection <DocMain
title={section ? this.sectionTitle : title} title={title}
/> description={description}
tableOfContents={tableOfContents}
<Content> post={post}
{section ? ( single
<main className={styles.wrapper}> />
<aside className={styles.sidebar}> )}
<Sidebar </Content>
location={location} </Layout>
sidebar={section} </>
collapsed={isApiSection} )
toc={ }
isApiSection &&
!location.pathname.includes(
'/references/introduction/'
)
}
tableOfContents={tableOfContents}
/>
</aside>
<DocMain
title={title}
description={description}
tableOfContents={
!isApiSection && tableOfContents
}
post={post}
/>
</main>
) : (
<DocMain
title={title}
description={description}
tableOfContents={tableOfContents}
post={post}
single
/>
)}
</Content>
</Layout>
</>
)
}
} }
export const pageQuery = graphql` export const pageQuery = graphql`
query DocBySlug($slug: String!) { query DocBySlug($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) { markdownRemark(fields: { slug: { eq: $slug } }) {
id id
tableOfContents(maxDepth: 3) tableOfContents(maxDepth: 3)
html html
htmlAst htmlAst
frontmatter { frontmatter {
title title
description description
} }
fields { fields {
section section
slug slug
} }
...PageFooter ...PageFooter
}
allSectionsYaml {
edges {
node {
title
description
link
}
}
}
} }
fragment PageFooter on MarkdownRemark { allSectionsYaml {
parent { edges {
... on File { node {
relativePath title
sourceInstanceName description
} link
} }
}
} }
}
fragment PageFooter on MarkdownRemark {
parent {
... on File {
relativePath
sourceInstanceName
}
}
}
` `

View File

@ -1,75 +1,75 @@
@import 'variables'; @import 'variables';
.wrapper { .wrapper {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
} }
.sidebar { .sidebar {
margin-top: $spacer / 2; margin-top: $spacer / 2;
margin-bottom: $spacer / 2; margin-bottom: $spacer / 2;
top: $spacer; top: $spacer;
order: 2; order: 2;
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
width: 27%; width: 27%;
margin-bottom: 0; margin-bottom: 0;
margin-top: 0; margin-top: 0;
order: 1; order: 1;
+ .main { + .main {
width: 73%; width: 73%;
}
} }
}
} }
.main { .main {
width: 100%; width: 100%;
background: $brand-white; background: $brand-white;
padding: 0 $spacer / 2; padding: 0 $spacer / 2;
border: 1px solid $brand-grey-lighter; border: 1px solid $brand-grey-lighter;
border-top: 0; border-top: 0;
order: 1; order: 1;
@media (min-width: $break-point--small) { @media (min-width: $break-point--small) {
padding-left: $spacer; padding-left: $spacer;
padding-right: $spacer; padding-right: $spacer;
} }
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
padding-left: $spacer * 2; padding-left: $spacer * 2;
padding-right: $spacer * 2; padding-right: $spacer * 2;
order: 2; order: 2;
} }
} }
.mainSingle { .mainSingle {
composes: main; composes: main;
max-width: 73%; max-width: 73%;
margin: auto; margin: auto;
} }
.version { .version {
color: $brand-grey-light; color: $brand-grey-light;
font-size: $font-size-base; font-size: $font-size-base;
font-family: $font-family-monospace; font-family: $font-family-monospace;
a { a {
font-size: $font-size-mini; font-size: $font-size-mini;
font-family: $font-family-base; font-family: $font-family-base;
font-weight: $font-weight-base; font-weight: $font-weight-base;
display: inline-block; display: inline-block;
margin-left: .5rem; margin-left: 0.5rem;
} }
} }
.pathName { .pathName {
font-size: $font-size-h3; font-size: $font-size-h3;
border-bottom: 1px solid $brand-grey-lighter; border-bottom: 1px solid $brand-grey-lighter;
padding-bottom: $spacer / 2; padding-bottom: $spacer / 2;
margin-top: $spacer * 2; margin-top: $spacer * 2;
margin-bottom: $spacer / $line-height; margin-bottom: $spacer / $line-height;
overflow-wrap: break-word; overflow-wrap: break-word;
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
} }

View File

@ -6,119 +6,117 @@ import styles from './Paths.module.scss'
import stylesDoc from '../Doc.module.scss' import stylesDoc from '../Doc.module.scss'
const ParameterExample = ({ properties }) => ( const ParameterExample = ({ properties }) => (
// //
// HEADS UP! // HEADS UP!
// //
// Constructing the example request body here based on the defined properties // Constructing the example request body here based on the defined properties
// where `key` is the name of the property, and `properties[key].example` is // where `key` is the name of the property, and `properties[key].example` is
// the value for it. // the value for it.
// //
// Making prism.js pick up on the strings only output didn't work out so well // Making prism.js pick up on the strings only output didn't work out so well
// so the spans and classes this plugin would add are added manually here. Since we // so the spans and classes this plugin would add are added manually here. Since we
// include the prism css file globally this is picked up by that. // include the prism css file globally this is picked up by that.
// //
// But this can only work if all keys and values are manually constructed here, which // But this can only work if all keys and values are manually constructed here, which
// is almost impossible to do for deep nested objects or arrays as example value. Running // is almost impossible to do for deep nested objects or arrays as example value. Running
// that code through `JSON.stringify` won't syntax highlight that part of the code. // that code through `JSON.stringify` won't syntax highlight that part of the code.
// //
<pre className="language-json"> <pre className="language-json">
<code className="language-json"> <code className="language-json">
{'{'} {'{'}
{properties && {properties &&
Object.keys(properties).map((key) => ( Object.keys(properties).map((key) => (
<div key={key}> <div key={key}>
<span className="token property">{` "${key}"`}</span> <span className="token property">{` "${key}"`}</span>
<span className="token operator">: </span> <span className="token operator">: </span>
{properties[key].type === 'string' && ( {properties[key].type === 'string' && (
<span className="token string">{`"${properties[key].example}"`}</span> <span className="token string">{`"${properties[key].example}"`}</span>
)} )}
{(properties[key].type === 'integer' || {(properties[key].type === 'integer' ||
properties[key].type === 'number') && ( properties[key].type === 'number') && (
<span className="token number"> <span className="token number">
{`${properties[key].example}`} {`${properties[key].example}`}
</span> </span>
)} )}
{(properties[key].type === 'array' || {(properties[key].type === 'array' ||
properties[key].type === 'object') && properties[key].type === 'object') &&
JSON.stringify(properties[key].example, null, 2)} JSON.stringify(properties[key].example, null, 2)}
, ,
</div> </div>
))} ))}
{'}'} {'}'}
</code> </code>
</pre> </pre>
) )
ParameterExample.propTypes = { ParameterExample.propTypes = {
properties: PropTypes.object properties: PropTypes.object
} }
const Parameters = ({ parameters }) => ( const Parameters = ({ parameters }) => (
<> <>
<h4 className={styles.subHeading}>Parameters</h4> <h4 className={styles.subHeading}>Parameters</h4>
{parameters.map((parameter) => { {parameters.map((parameter) => {
const { name, type, required, description, schema } = parameter const { name, type, required, description, schema } = parameter
return ( return (
<div className={styles.parameters} key={parameter.name}> <div className={styles.parameters} key={parameter.name}>
<h5> <h5>
<code>{name}</code> <code>{name}</code>
{required && ( {required && (
<span <span
className={styles.parameterRequired} className={styles.parameterRequired}
title="required parameter" title="required parameter"
> >
* *
</span> </span>
)} )}
<span className={styles.parameterType}>{type}</span> <span className={styles.parameterType}>{type}</span>
</h5> </h5>
<p>{description}</p> <p>{description}</p>
{schema && ( {schema && <ParameterExample properties={schema.properties} />}
<ParameterExample properties={schema.properties} /> </div>
)} )
</div> })}
) </>
})}
</>
) )
Parameters.propTypes = { Parameters.propTypes = {
parameters: PropTypes.array.isRequired parameters: PropTypes.array.isRequired
} }
const Responses = ({ responses }) => ( const Responses = ({ responses }) => (
<> <>
<h4 className={styles.subHeading}>Responses</h4> <h4 className={styles.subHeading}>Responses</h4>
{Object.keys(responses).map((key) => ( {Object.keys(responses).map((key) => (
<div key={key} className={styles.response}> <div key={key} className={styles.response}>
<code>{key}</code> {responses[key].description} <code>{key}</code> {responses[key].description}
</div> </div>
))} ))}
</> </>
) )
Responses.propTypes = { Responses.propTypes = {
responses: PropTypes.object.isRequired responses: PropTypes.object.isRequired
} }
const Method = ({ keyName, value }) => { const Method = ({ keyName, value }) => {
const { summary, description, parameters, responses } = value const { summary, description, parameters, responses } = value
return ( return (
<div className={styles.method}> <div className={styles.method}>
<h3 className={styles.pathMethod} data-type={keyName}> <h3 className={styles.pathMethod} data-type={keyName}>
{keyName} {keyName}
</h3> </h3>
<p>{summary}</p> <p>{summary}</p>
{description && <p>{description}</p>} {description && <p>{description}</p>}
{/* {/*
{consumes && {consumes &&
consumes.map((item, i) => ( consumes.map((item, i) => (
<div key={i}> <div key={i}>
@ -127,32 +125,32 @@ const Method = ({ keyName, value }) => {
))} ))}
*/} */}
{parameters && parameters.length && ( {parameters && parameters.length && (
<Parameters parameters={parameters} /> <Parameters parameters={parameters} />
)} )}
{responses && Object.keys(responses).length !== 0 && ( {responses && Object.keys(responses).length !== 0 && (
<Responses responses={responses} /> <Responses responses={responses} />
)} )}
</div> </div>
) )
} }
Method.propTypes = { Method.propTypes = {
keyName: PropTypes.string, keyName: PropTypes.string,
value: PropTypes.object value: PropTypes.object
} }
const Paths = ({ paths }) => const Paths = ({ paths }) =>
Object.entries(paths).map(([key, value]) => ( Object.entries(paths).map(([key, value]) => (
<div key={key} id={slugify(cleanPathKey(key))}> <div key={key} id={slugify(cleanPathKey(key))}>
<h2 className={stylesDoc.pathName}> <h2 className={stylesDoc.pathName}>
<code>{cleanPathKey(key)}</code> <code>{cleanPathKey(key)}</code>
</h2> </h2>
{Object.entries(value).map(([key, value]) => ( {Object.entries(value).map(([key, value]) => (
<Method key={key} keyName={key} value={value} /> <Method key={key} keyName={key} value={value} />
))} ))}
</div> </div>
)) ))
export default Paths export default Paths

View File

@ -1,74 +1,74 @@
@import 'variables'; @import 'variables';
.pathMethod { .pathMethod {
font-size: $font-size-base; font-size: $font-size-base;
font-family: $font-family-monospace; font-family: $font-family-monospace;
margin-bottom: $spacer / 4; margin-bottom: $spacer / 4;
margin-top: 0; margin-top: 0;
display: inline-block; display: inline-block;
padding: $spacer / 8 $spacer / 3; padding: $spacer / 8 $spacer / 3;
border-radius: $border-radius; border-radius: $border-radius;
text-transform: uppercase; text-transform: uppercase;
&[data-type='get'] { &[data-type='get'] {
background: rgba($green, .4); background: rgba($green, 0.4);
} }
&[data-type='post'] { &[data-type='post'] {
background: rgba($brand-blue, .4); background: rgba($brand-blue, 0.4);
} }
&[data-type='put'] { &[data-type='put'] {
background: rgba($brand-violet, .3); background: rgba($brand-violet, 0.3);
} }
&[data-type='delete'] { &[data-type='delete'] {
background: rgba($red, .4); background: rgba($red, 0.4);
} }
} }
.method { .method {
padding: $spacer / 2; padding: $spacer / 2;
border: 1px solid $brand-grey-lighter; border: 1px solid $brand-grey-lighter;
margin-bottom: $spacer; margin-bottom: $spacer;
border-radius: $border-radius; border-radius: $border-radius;
} }
.subHeading { .subHeading {
font-size: $font-size-h5; font-size: $font-size-h5;
} }
.parameters { .parameters {
h5 { h5 {
font-size: $font-size-small; font-size: $font-size-small;
margin-bottom: $spacer / 4; margin-bottom: $spacer / 4;
} }
pre { pre {
max-height: 80vh; max-height: 80vh;
code { code {
padding: $spacer / $line-height; padding: $spacer / $line-height;
}
} }
}
} }
.parameterRequired { .parameterRequired {
font-size: $font-size-small; font-size: $font-size-small;
vertical-align: top; vertical-align: top;
color: $brand-purple; color: $brand-purple;
} }
.parameterType { .parameterType {
font-weight: $font-weight-base; font-weight: $font-weight-base;
margin-left: $spacer / 4; margin-left: $spacer / 4;
color: $brand-grey-light; color: $brand-grey-light;
} }
.response { .response {
margin-bottom: $spacer / 4; margin-bottom: $spacer / 4;
code { code {
margin-right: $spacer / 4; margin-right: $spacer / 4;
} }
} }

View File

@ -7,37 +7,37 @@ import { cleanPathKey } from './utils'
import stylesSidebar from '../../components/Sidebar.module.scss' import stylesSidebar from '../../components/Sidebar.module.scss'
const Toc = ({ data }) => { const Toc = ({ data }) => {
const Ids = [] const Ids = []
const items = Object.keys(data.paths).map((key) => { const items = Object.keys(data.paths).map((key) => {
Ids.push(slugify(cleanPathKey(key))) Ids.push(slugify(cleanPathKey(key)))
return (
<li key={key}>
<Scroll
type="id"
element={`${slugify(cleanPathKey(key))}`}
offset={-20}
>
<code>{cleanPathKey(key)}</code>
</Scroll>
</li>
)
})
return ( return (
<Scrollspy <li key={key}>
items={Ids} <Scroll
currentClassName={stylesSidebar.scrollspyActive} type="id"
offset={-100} element={`${slugify(cleanPathKey(key))}`}
offset={-20}
> >
{items} <code>{cleanPathKey(key)}</code>
</Scrollspy> </Scroll>
</li>
) )
})
return (
<Scrollspy
items={Ids}
currentClassName={stylesSidebar.scrollspyActive}
offset={-100}
>
{items}
</Scrollspy>
)
} }
Toc.propTypes = { Toc.propTypes = {
data: PropTypes.oneOfType([PropTypes.array, PropTypes.object]) data: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
} }
export default Toc export default Toc

View File

@ -18,136 +18,133 @@ import stylesDoc from '../Doc.module.scss'
import styles from './index.module.scss' import styles from './index.module.scss'
const SwaggerMeta = ({ contact, license }) => ( const SwaggerMeta = ({ contact, license }) => (
<ul className={styles.swaggerMeta}> <ul className={styles.swaggerMeta}>
{contact && ( {contact && (
<li> <li>
<a href={`mailto:${contact.email}`}>{contact.email}</a> <a href={`mailto:${contact.email}`}>{contact.email}</a>
</li> </li>
)} )}
{license && ( {license && (
<li> <li>
<a href={license.url}>{license.name}</a> <a href={license.url}>{license.name}</a>
</li> </li>
)} )}
</ul> </ul>
) )
SwaggerMeta.propTypes = { SwaggerMeta.propTypes = {
contact: PropTypes.object, contact: PropTypes.object,
license: PropTypes.object license: PropTypes.object
} }
const BasePath = ({ host, basePath }) => ( const BasePath = ({ host, basePath }) => (
<div className={styles.basePath}> <div className={styles.basePath}>
<h2>Base Path</h2> <h2>Base Path</h2>
<code> <code>
<span>{host}</span> <span>{host}</span>
{basePath} {basePath}
</code> </code>
</div> </div>
) )
BasePath.propTypes = { BasePath.propTypes = {
host: PropTypes.string, host: PropTypes.string,
basePath: PropTypes.string basePath: PropTypes.string
} }
export default class ApiSwaggerTemplate extends Component { export default class ApiSwaggerTemplate extends Component {
static propTypes = { static propTypes = {
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
location: PropTypes.object.isRequired, location: PropTypes.object.isRequired,
pageContext: PropTypes.object.isRequired pageContext: PropTypes.object.isRequired
}
// output section title as defined in sections.yml
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => {
// compare section against section title from sections.yml
if (node.title.toLowerCase().includes('references')) {
return node.title
} }
})
// output section title as defined in sections.yml render() {
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => { const { location, pageContext } = this.props
// compare section against section title from sections.yml const { api } = pageContext
if (node.title.toLowerCase().includes('references')) { const { host, basePath, info, paths } = api
return node.title const { title, description, version, license, contact } = info
}
})
render() { return (
const { location, pageContext } = this.props <>
const { api } = pageContext <Helmet>
const { host, basePath, info, paths } = api <body className="references" />
const { title, description, version, license, contact } = info </Helmet>
return ( <Seo
<> title={title}
<Helmet> description={description}
<body className="references" /> slug={pageContext.slug}
</Helmet> article
location={location}
/>
<Seo <Layout location={location}>
title={title} <HeaderSection title={this.sectionTitle} />
description={description}
slug={pageContext.slug} <Content>
article <main className={stylesDoc.wrapper}>
location={location} <aside className={stylesDoc.sidebar}>
<Sidebar
location={location}
sidebar="references"
collapsed
toc
tocComponent={<Toc data={api} />}
/>
</aside>
<article className={stylesDoc.main}>
<DocHeader
title={title}
description={description}
prepend={
<span className={stylesDoc.version}>
<span>v{version}</span>
</span>
}
/> />
<Layout location={location}> {(contact || license) && (
<HeaderSection title={this.sectionTitle} /> <SwaggerMeta contact={contact} license={license} />
)}
<Content> {(host || basePath) && (
<main className={stylesDoc.wrapper}> <BasePath host={host} basePath={basePath} />
<aside className={stylesDoc.sidebar}> )}
<Sidebar
location={location}
sidebar="references"
collapsed
toc
tocComponent={<Toc data={api} />}
/>
</aside>
<article className={stylesDoc.main}>
<DocHeader
title={title}
description={description}
prepend={
<span className={stylesDoc.version}>
<span>v{version}</span>
</span>
}
/>
{(contact || license) && ( <Paths paths={paths} />
<SwaggerMeta
contact={contact}
license={license}
/>
)}
{(host || basePath) && ( <DocFooter
<BasePath host={host} basePath={basePath} /> url={`https://github.com/oceanprotocol/${title.toLowerCase()}`}
)} externalName={`${title} Swagger spec`}
/>
<Paths paths={paths} /> </article>
</main>
<DocFooter </Content>
url={`https://github.com/oceanprotocol/${title.toLowerCase()}`} </Layout>
externalName={`${title} Swagger spec`} </>
/> )
</article> }
</main>
</Content>
</Layout>
</>
)
}
} }
export const apiSwaggerQuery = graphql` export const apiSwaggerQuery = graphql`
query { query {
allSectionsYaml { allSectionsYaml {
edges { edges {
node { node {
title title
description description
link link
}
}
} }
}
} }
}
` `

View File

@ -1,42 +1,42 @@
@import 'variables'; @import 'variables';
.swaggerMeta { .swaggerMeta {
margin-top: -($spacer); margin-top: -($spacer);
padding: 0; padding: 0;
font-size: $font-size-small; font-size: $font-size-small;
li { li {
display: inline-block; display: inline-block;
margin-left: $spacer; margin-left: $spacer;
&:first-child { &:first-child {
margin-left: 0; margin-left: 0;
}
&:before {
display: none;
}
} }
&:before {
display: none;
}
}
} }
.basePath { .basePath {
margin-top: $spacer; margin-top: $spacer;
h2 { h2 {
font-size: $font-size-h3; font-size: $font-size-h3;
border-bottom: 1px solid $brand-grey-lighter; border-bottom: 1px solid $brand-grey-lighter;
padding-bottom: $spacer / 2; padding-bottom: $spacer / 2;
margin-top: $spacer * 2; margin-top: $spacer * 2;
margin-bottom: $spacer; margin-bottom: $spacer;
} }
span { span {
color: $brand-grey-light; color: $brand-grey-light;
} }
code { code {
// stylelint-disable-next-line // stylelint-disable-next-line
font-size: $font-size-large !important; font-size: $font-size-large !important;
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
} }
} }

View File

@ -1,13 +1,13 @@
export const cleanPathKey = (key) => { export const cleanPathKey = (key) => {
let keyCleaned = key let keyCleaned = key
if (key.includes('aquarius')) { if (key.includes('aquarius')) {
keyCleaned = key.replace(/\/api\/v1\/aquarius/gi, '') keyCleaned = key.replace(/\/api\/v1\/aquarius/gi, '')
} }
if (key.includes('brizo')) { if (key.includes('brizo')) {
keyCleaned = key.replace(/\/api\/v1\/brizo/gi, '') keyCleaned = key.replace(/\/api\/v1\/brizo/gi, '')
} }
return keyCleaned return keyCleaned
} }

View File

@ -7,255 +7,228 @@ import styles from './Entities.module.scss'
import { filterByKindOfProperty } from './utils' import { filterByKindOfProperty } from './utils'
const Type = ({ type }) => { const Type = ({ type }) => {
let isArray = false let isArray = false
if (type.type === 'array') { if (type.type === 'array') {
isArray = true isArray = true
type = type.elementType type = type.elementType
} }
const { name, type: typeOfType, typeArguments, id } = type const { name, type: typeOfType, typeArguments, id } = type
const isInternal = typeOfType === 'reference' && id const isInternal = typeOfType === 'reference' && id
return ( return (
<div className={styles.type}> <div className={styles.type}>
<span> <span>
{isInternal && ( {isInternal && (
<Scroll <Scroll type="id" element={`${name && slugify(name)}`} offset={-20}>
type="id" {type.name}
element={`${name && slugify(name)}`} </Scroll>
offset={-20} )}
> {!isInternal && <span>{type.name}</span>}
{type.name} </span>
</Scroll>
)}
{!isInternal && <span>{type.name}</span>}
</span>
{typeArguments && ( {typeArguments && (
<span> <span>
<span className={styles.typeSymbol}>&lt;</span> <span className={styles.typeSymbol}>&lt;</span>
<span> <span>
{typeArguments.map((typeArgument, i) => ( {typeArguments.map((typeArgument, i) => (
<span key={shortid.generate()}> <span key={shortid.generate()}>
{i !== 0 && ( {i !== 0 && <span className={styles.typeSymbol}>, </span>}
<span className={styles.typeSymbol}> <Type type={typeArgument} />
,{' '} </span>
</span> ))}
)} </span>
<Type type={typeArgument} /> <span className={styles.typeSymbol}>&gt;</span>
</span> </span>
))} )}
</span>
<span className={styles.typeSymbol}>&gt;</span>
</span>
)}
{isArray && <span className={styles.typeSymbol}>[]</span>} {isArray && <span className={styles.typeSymbol}>[]</span>}
</div> </div>
) )
} }
Type.propTypes = { Type.propTypes = {
type: PropTypes.object.isRequired type: PropTypes.object.isRequired
} }
const PropertyDetails = ({ property }) => { const PropertyDetails = ({ property }) => {
const { type } = property const { type } = property
return ( return (
<div> <div>
<Type type={type} /> <Type type={type} />
</div> </div>
) )
} }
PropertyDetails.propTypes = { PropertyDetails.propTypes = {
property: PropTypes.object property: PropTypes.object
} }
const MethodDetails = ({ property }) => { const MethodDetails = ({ property }) => {
const signature = property.signatures[0] const signature = property.signatures[0]
const { parameters, type } = signature const { parameters, type } = signature
return ( return (
<> <>
{parameters && parameters.length && ( {parameters && parameters.length && (
<div> <div>
<h4 className={styles.subHeading}>Parameters</h4> <h4 className={styles.subHeading}>Parameters</h4>
{parameters.map((parameter) => { {parameters.map((parameter) => {
const { name, type, flags, comment } = parameter const { name, type, flags, comment } = parameter
const { isOptional } = flags const { isOptional } = flags
const description = const description = comment && (comment.text || comment.shortText)
comment && (comment.text || comment.shortText)
return ( return (
<div <div className={styles.parameters} key={shortid.generate()}>
className={styles.parameters} <h5>
key={shortid.generate()} <code>{name}</code>
> {isOptional && (
<h5> <span
<code>{name}</code> className={styles.parameterOptional}
{isOptional && ( title="optional parameter"
<span >
className={styles.parameterOptional} ?
title="optional parameter" </span>
> )}
? </h5>
</span> <Type type={type} />
)}
</h5>
<Type type={type} />
<p>{description}</p> <p>{description}</p>
</div> </div>
) )
})} })}
</div> </div>
)} )}
{type && ( {type && (
<div> <div>
<h4 className={styles.subHeading}>Returns</h4> <h4 className={styles.subHeading}>Returns</h4>
<Type type={type} /> <Type type={type} />
</div> </div>
)} )}
</> </>
) )
} }
MethodDetails.propTypes = { MethodDetails.propTypes = {
property: PropTypes.object property: PropTypes.object
} }
const PropertyWrapper = ({ property, sourceUrl, parentAnchor }) => { const PropertyWrapper = ({ property, sourceUrl, parentAnchor }) => {
const { const { name, kindString, flags, signatures, sources, decorators } = property
name, const { isPublic, isStatic } = flags
kindString, const signature = signatures && signatures[0]
flags, const comment = (signature && signature.comment) || property.comment
signatures, const { fileName, line } = sources[0]
sources, const deprecation = (decorators || []).filter(
decorators ({ name }) => name === 'deprecated'
} = property )[0] // Assuming deprecated annotation
const { isPublic, isStatic } = flags let deprecatedUse, deprecatedSlug
const signature = signatures && signatures[0] if (deprecation) {
const comment = (signature && signature.comment) || property.comment deprecatedUse = deprecation.arguments.alternative.replace(/('|")/g, '')
const { fileName, line } = sources[0] deprecatedSlug = deprecatedUse && slugify(deprecatedUse.replace('.', '-'))
const deprecation = (decorators || []).filter( }
({ name }) => name === 'deprecated'
)[0] // Assuming deprecated annotation
let deprecatedUse, deprecatedSlug
if (deprecation) {
deprecatedUse = deprecation.arguments.alternative.replace(/('|")/g, '')
deprecatedSlug =
deprecatedUse && slugify(deprecatedUse.replace('.', '-'))
}
const sourceLink = `${sourceUrl}${fileName}#L${line}` const sourceLink = `${sourceUrl}${fileName}#L${line}`
return ( return (
<div <div
className={styles.property} className={styles.property}
data-private={!isPublic} data-private={!isPublic}
data-deprecated={!!deprecation} data-deprecated={!!deprecation}
id={`${parentAnchor}-${name && slugify(name)}`} id={`${parentAnchor}-${name && slugify(name)}`}
> >
<h3 className={styles.propertyName}>{name}</h3> <h3 className={styles.propertyName}>{name}</h3>
<div <div className={styles.propertyType} data-type={kindString.toLowerCase()}>
className={styles.propertyType} {kindString}
data-type={kindString.toLowerCase()} </div>
>
{kindString}
</div>
{isStatic && <div className={styles.propertyModifier}>static</div>} {isStatic && <div className={styles.propertyModifier}>static</div>}
{!isPublic && ( {!isPublic && (
<div className={styles.propertyModifier} data-secondary> <div className={styles.propertyModifier} data-secondary>
private private
</div>
)}
{comment && !deprecation && (
<div className={styles.propertyDescription}>
{comment.text || comment.shortText}
</div>
)}
{deprecation && (
<div className={styles.deprecation}>
<strong>Deprecated</strong>: use{' '}
<code>
<Scroll
type="id"
element={`${deprecatedSlug}`}
offset={-20}
>
{deprecatedUse}
</Scroll>
</code>{' '}
instead
</div>
)}
{!deprecation &&
(() => {
switch (kindString) {
case 'Method':
return <MethodDetails property={property} />
case 'Property':
return <PropertyDetails property={property} />
}
})()}
{fileName && (
<a
className={styles.sourceLink}
href={sourceLink}
target="_blank"
rel="noopener noreferrer"
>
{`${fileName}#L${line}`}
</a>
)}
</div> </div>
) )}
{comment && !deprecation && (
<div className={styles.propertyDescription}>
{comment.text || comment.shortText}
</div>
)}
{deprecation && (
<div className={styles.deprecation}>
<strong>Deprecated</strong>: use{' '}
<code>
<Scroll type="id" element={`${deprecatedSlug}`} offset={-20}>
{deprecatedUse}
</Scroll>
</code>{' '}
instead
</div>
)}
{!deprecation &&
(() => {
switch (kindString) {
case 'Method':
return <MethodDetails property={property} />
case 'Property':
return <PropertyDetails property={property} />
}
})()}
{fileName && (
<a
className={styles.sourceLink}
href={sourceLink}
target="_blank"
rel="noopener noreferrer"
>
{`${fileName}#L${line}`}
</a>
)}
</div>
)
} }
PropertyWrapper.propTypes = { PropertyWrapper.propTypes = {
property: PropTypes.object, property: PropTypes.object,
sourceUrl: PropTypes.string, sourceUrl: PropTypes.string,
parentAnchor: PropTypes.string parentAnchor: PropTypes.string
} }
const Entities = ({ entities, sourceUrl }) => const Entities = ({ entities, sourceUrl }) =>
entities.map(({ name, comment, children }) => ( entities.map(({ name, comment, children }) => (
<div key={shortid.generate()} id={name && slugify(name)}> <div key={shortid.generate()} id={name && slugify(name)}>
<h2 className={styles.entityName}> <h2 className={styles.entityName}>
<code>{name}</code> <code>{name}</code>
</h2> </h2>
{comment && ( {comment && (
<div className={styles.entityDescription}> <div className={styles.entityDescription}>
{comment.text || comment.shortText} {comment.text || comment.shortText}
</div>
)}
{children &&
children
.filter(filterByKindOfProperty)
.map((property) => (
<PropertyWrapper
key={shortid.generate()}
property={property}
sourceUrl={sourceUrl}
parentAnchor={name && slugify(name)}
/>
))}
</div> </div>
)) )}
{children &&
children
.filter(filterByKindOfProperty)
.map((property) => (
<PropertyWrapper
key={shortid.generate()}
property={property}
sourceUrl={sourceUrl}
parentAnchor={name && slugify(name)}
/>
))}
</div>
))
Entities.propTypes = { Entities.propTypes = {
entities: PropTypes.array.isRequired, entities: PropTypes.array.isRequired,
sourceUrl: PropTypes.string sourceUrl: PropTypes.string
} }
export default Entities export default Entities

View File

@ -1,165 +1,165 @@
@import 'variables'; @import 'variables';
.entityName { .entityName {
// stylelint-disable value-keyword-case // stylelint-disable value-keyword-case
composes: pathname from '../Doc.module.scss'; composes: pathname from '../Doc.module.scss';
// stylelint-enable value-keyword-case // stylelint-enable value-keyword-case
font-size: $font-size-h2; font-size: $font-size-h2;
} }
.entityDescription { .entityDescription {
padding-bottom: $spacer; padding-bottom: $spacer;
white-space: pre-line; white-space: pre-line;
} }
.property { .property {
padding: $spacer / 2; padding: $spacer / 2;
border: 1px solid $brand-grey-lighter; border: 1px solid $brand-grey-lighter;
margin-bottom: $spacer; margin-bottom: $spacer;
border-radius: $border-radius; border-radius: $border-radius;
position: relative; position: relative;
&[data-deprecated='true'] { &[data-deprecated='true'] {
> *:not(.deprecation) { > *:not(.deprecation) {
opacity: .5; opacity: 0.5;
}
code {
opacity: 1;
background: none;
padding: 0;
}
.sourceLink {
display: none;
}
} }
code {
opacity: 1;
background: none;
padding: 0;
}
.sourceLink {
display: none;
}
}
} }
.propertyName, .propertyName,
.propertyType, .propertyType,
.propertyModifier { .propertyModifier {
font-size: $font-size-base; font-size: $font-size-base;
font-family: $font-family-monospace; font-family: $font-family-monospace;
margin-bottom: $spacer / 4; margin-bottom: $spacer / 4;
margin-top: 0; margin-top: 0;
display: inline-block; display: inline-block;
padding: 0 $spacer / 4; padding: 0 $spacer / 4;
border-radius: $border-radius; border-radius: $border-radius;
vertical-align: middle; vertical-align: middle;
} }
.propertyName { .propertyName {
font-size: $font-size-large; font-size: $font-size-large;
padding: 0; padding: 0;
margin-right: $spacer / 3; margin-right: $spacer / 3;
} }
.propertyType, .propertyType,
.propertyModifier { .propertyModifier {
font-size: $font-size-small; font-size: $font-size-small;
color: $brand-grey; color: $brand-grey;
margin-right: $spacer / 4; margin-right: $spacer / 4;
} }
.propertyType { .propertyType {
&[data-type='method'] { &[data-type='method'] {
background: rgba($green, .3); background: rgba($green, 0.3);
} }
&[data-type='property'] { &[data-type='property'] {
background: rgba($yellow, .3); background: rgba($yellow, 0.3);
} }
} }
.propertyModifier { .propertyModifier {
background: rgba($red, .2); background: rgba($red, 0.2);
&[data-secondary] { &[data-secondary] {
background: rgba($brand-blue, .2); background: rgba($brand-blue, 0.2);
} }
} }
.propertyDescription { .propertyDescription {
margin-bottom: $spacer; margin-bottom: $spacer;
} }
.sourceLink { .sourceLink {
display: block; display: block;
font-size: $font-size-mini; font-size: $font-size-mini;
color: $brand-grey-light; color: $brand-grey-light;
margin-top: $spacer / 2; margin-top: $spacer / 2;
&:hover, &:hover,
&:focus { &:focus {
transform: none; transform: none;
} }
@media (min-width: $break-point--large) { @media (min-width: $break-point--large) {
margin-top: 0; margin-top: 0;
position: absolute; position: absolute;
bottom: $spacer / 2; bottom: $spacer / 2;
right: $spacer / 2; right: $spacer / 2;
} }
} }
.deprecation { .deprecation {
font-size: $font-size-small; font-size: $font-size-small;
margin-top: $spacer / 4; margin-top: $spacer / 4;
strong { strong {
color: $brand-grey-light; color: $brand-grey-light;
} }
} }
.type { .type {
display: inline-block; display: inline-block;
color: $brand-grey; color: $brand-grey;
font-family: $font-family-monospace; font-family: $font-family-monospace;
font-size: $font-size-small; font-size: $font-size-small;
a { a {
&:hover { &:hover {
opacity: .6; opacity: 0.6;
}
} }
}
} }
.typeSymbol { .typeSymbol {
opacity: .6; opacity: 0.6;
} }
.subHeading { .subHeading {
font-size: $font-size-base; font-size: $font-size-base;
border-bottom: 1px solid $brand-grey-lighter; border-bottom: 1px solid $brand-grey-lighter;
padding-bottom: $spacer / 4; padding-bottom: $spacer / 4;
margin-bottom: $spacer / 4; margin-bottom: $spacer / 4;
color: $brand-grey; color: $brand-grey;
} }
.parameters { .parameters {
margin-top: $spacer / 1.5; margin-top: $spacer / 1.5;
h5, h5,
p { p {
margin: 0; margin: 0;
} }
h5 { h5 {
font-size: $font-size-small; font-size: $font-size-small;
margin-bottom: $spacer / 4; margin-bottom: $spacer / 4;
margin-right: $spacer / 4; margin-right: $spacer / 4;
margin-left: -(.2rem); margin-left: -(0.2rem);
display: inline-block; display: inline-block;
} }
code { code {
padding: .2rem; padding: 0.2rem;
} }
} }
.parameterOptional { .parameterOptional {
font-size: $font-size-small; font-size: $font-size-small;
vertical-align: top; vertical-align: top;
color: $brand-purple; color: $brand-purple;
} }

View File

@ -8,63 +8,59 @@ import { filterByKindOfProperty } from './utils'
import stylesSidebar from '../../components/Sidebar.module.scss' import stylesSidebar from '../../components/Sidebar.module.scss'
export default class Toc extends PureComponent { export default class Toc extends PureComponent {
static propTypes = { static propTypes = {
data: PropTypes.array data: PropTypes.array
} }
subItems = (children, parentName) => subItems = (children, parentName) =>
children && children &&
children.filter(filterByKindOfProperty).map(({ name, decorators }) => { children.filter(filterByKindOfProperty).map(({ name, decorators }) => {
const deprecation = (decorators || []).filter( const deprecation = (decorators || []).filter(
({ name }) => name === 'deprecated' ({ name }) => name === 'deprecated'
)[0] // Assuming deprecated annotation )[0] // Assuming deprecated annotation
return ( return (
<li key={shortid.generate()}> <li key={shortid.generate()}>
<Scroll <Scroll
type="id" type="id"
element={`${parentName}-${name && slugify(name)}`} element={`${parentName}-${name && slugify(name)}`}
data-deprecated={!!deprecation} data-deprecated={!!deprecation}
offset={-20} offset={-20}
> >
<code>{name}</code> <code>{name}</code>
</Scroll> </Scroll>
</li> </li>
) )
})
items = this.props.data.map(({ name, children }) => {
const subIds = []
const parentName = name
subIds.push(
children &&
children.filter(filterByKindOfProperty).map(({ name }) => {
return `${parentName}-${name && slugify(name)}`
})
)
return (
<li key={shortid.generate()}>
<Scroll
type="id"
element={`${name && slugify(name)}`}
offset={-20}
>
<code>{name}</code>
</Scroll>
<Scrollspy
items={subIds[0]}
currentClassName={stylesSidebar.scrollspyActive}
offset={-30}
>
{this.subItems(children, name)}
</Scrollspy>
</li>
)
}) })
render() { items = this.props.data.map(({ name, children }) => {
return <ul>{this.items}</ul> const subIds = []
} const parentName = name
subIds.push(
children &&
children.filter(filterByKindOfProperty).map(({ name }) => {
return `${parentName}-${name && slugify(name)}`
})
)
return (
<li key={shortid.generate()}>
<Scroll type="id" element={`${name && slugify(name)}`} offset={-20}>
<code>{name}</code>
</Scroll>
<Scrollspy
items={subIds[0]}
currentClassName={stylesSidebar.scrollspyActive}
offset={-30}
>
{this.subItems(children, name)}
</Scrollspy>
</li>
)
})
render() {
return <ul>{this.items}</ul>
}
} }

View File

@ -16,95 +16,89 @@ import Toc from './Toc'
import stylesDoc from '../Doc.module.scss' import stylesDoc from '../Doc.module.scss'
export default class TypedocTemplate extends Component { export default class TypedocTemplate extends Component {
static propTypes = { static propTypes = {
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
location: PropTypes.object.isRequired, location: PropTypes.object.isRequired,
pageContext: PropTypes.object.isRequired pageContext: PropTypes.object.isRequired
}
typedocCleaned = cleanTypedocData(
this.props.pageContext.typedoc,
this.props.pageContext.classes
)
// output section title as defined in sections.yml
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => {
// compare section against section title from sections.yml
if (node.title.toLowerCase().includes('references')) {
return node.title
} }
})
typedocCleaned = cleanTypedocData( render() {
this.props.pageContext.typedoc, const { location, pageContext } = this.props
this.props.pageContext.classes const { typedoc } = pageContext
) const { info } = typedoc
const { title, description, version, sourceUrl } = info
// output section title as defined in sections.yml return (
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => { <>
// compare section against section title from sections.yml <Helmet>
if (node.title.toLowerCase().includes('references')) { <body className="references" />
return node.title </Helmet>
}
})
render() { <Seo
const { location, pageContext } = this.props title={title}
const { typedoc } = pageContext description={description}
const { info } = typedoc slug={pageContext.slug}
const { title, description, version, sourceUrl } = info article
location={location}
/>
return ( <Layout location={location}>
<> <HeaderSection title={this.sectionTitle} />
<Helmet>
<body className="references" />
</Helmet>
<Seo <Content>
title={title} <main className={stylesDoc.wrapper}>
description={description} <aside className={stylesDoc.sidebar}>
slug={pageContext.slug} <Sidebar
article location={location}
location={location} sidebar="references"
collapsed
toc
tocComponent={<Toc data={this.typedocCleaned} />}
/>
</aside>
<article className={stylesDoc.main}>
<DocHeader
title={title}
description={description}
prepend={<span className={stylesDoc.version}>{version}</span>}
/> />
<Layout location={location}> <Entities
<HeaderSection title={this.sectionTitle} /> entities={this.typedocCleaned}
sourceUrl={sourceUrl}
<Content> />
<main className={stylesDoc.wrapper}> </article>
<aside className={stylesDoc.sidebar}> </main>
<Sidebar </Content>
location={location} </Layout>
sidebar="references" </>
collapsed )
toc }
tocComponent={
<Toc data={this.typedocCleaned} />
}
/>
</aside>
<article className={stylesDoc.main}>
<DocHeader
title={title}
description={description}
prepend={
<span className={stylesDoc.version}>
{version}
</span>
}
/>
<Entities
entities={this.typedocCleaned}
sourceUrl={sourceUrl}
/>
</article>
</main>
</Content>
</Layout>
</>
)
}
} }
export const TypedocQuery = graphql` export const TypedocQuery = graphql`
query { query {
allSectionsYaml { allSectionsYaml {
edges { edges {
node { node {
title title
description description
link link
}
}
} }
}
} }
}
` `

View File

@ -1,48 +1,44 @@
export const cleanTypedocData = (data, useClasses) => { export const cleanTypedocData = (data, useClasses) => {
const nodes = data.children const nodes = data.children
const cleanData = nodes const cleanData = nodes
.map((node) => { .map((node) => {
const child = const child =
node.children && node.children &&
node.children.filter( node.children.filter(({ kindString }) => kindString === 'Class')[0]
({ kindString }) => kindString === 'Class'
)[0]
return { return {
...node, ...node,
name: node.name.replace(/"/g, '').replace('src/', ''), name: node.name.replace(/"/g, '').replace('src/', ''),
child child
} }
}) })
.filter(({ name }) => (useClasses || []).includes(name)) .filter(({ name }) => (useClasses || []).includes(name))
.sort((a, b) => useClasses.indexOf(a.name) - useClasses.indexOf(b.name)) .sort((a, b) => useClasses.indexOf(a.name) - useClasses.indexOf(b.name))
.map(({ child }) => child) .map(({ child }) => child)
.map((node) => ({ .map((node) => ({
...node, ...node,
children: children:
node && node && node.children && node.children.sort((a, b) => a.id - b.id)
node.children && }))
node.children.sort((a, b) => a.id - b.id)
}))
return cleanData return cleanData
} }
// more kinds: 'Property', 'Enumeration' // more kinds: 'Property', 'Enumeration'
const showKindOfProperty = { const showKindOfProperty = {
Method: { onlyPublic: true }, Method: { onlyPublic: true },
Property: { onlyPublic: true } Property: { onlyPublic: true }
} }
export const filterByKindOfProperty = ({ kindString, flags }) => { export const filterByKindOfProperty = ({ kindString, flags }) => {
const config = showKindOfProperty[kindString] const config = showKindOfProperty[kindString]
if (!config) return if (!config) return
// filter out static methods by default // filter out static methods by default
if (flags.isStatic) return if (flags.isStatic) return
if (config.onlyPublic && !flags.isPublic) return if (config.onlyPublic && !flags.isPublic) return
return true return true
} }