mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
Merge pull request #5326 from yangshun/yangshun/about-cleanup
chore(about): clean up unused files
This commit is contained in:
15 files changed
+7
-1013
No files matched your search
@@ -1,8 +1,3 @@
|
||||
node_modules
|
||||
build
|
||||
.docusaurus
|
||||
docs/client
|
||||
docs/gotrue/client
|
||||
docs/postgrest/client
|
||||
docs/realtime/client
|
||||
docs/reference
|
||||
@@ -1,268 +0,0 @@
|
||||
/**
|
||||
* Usage:
|
||||
* ts-node ReferenceGenerator.ts -o {output_dir} {input}.yml
|
||||
*
|
||||
* Example:
|
||||
* ts-node ReferenceGenerator.ts -o docs/client spec/supabase.yml
|
||||
*/
|
||||
|
||||
import Example from './spec/gen/components/Example'
|
||||
import Page from './spec/gen/components/Page'
|
||||
import Sidebar from './spec/gen/components/Sidebar'
|
||||
import SidebarCategory from './spec/gen/components/SidebarCategory'
|
||||
import Tab from './spec/gen/components/Tab'
|
||||
import Tabs from './spec/gen/components/Tabs'
|
||||
import { slugify, tsDocCommentToMdComment, writeToDisk } from './spec/gen/lib/helpers'
|
||||
import { TsDoc, OpenRef } from './spec/gen/definitions'
|
||||
|
||||
const yaml = require('js-yaml')
|
||||
const fs = require('fs')
|
||||
|
||||
const main = (fileNames, options) => {
|
||||
try {
|
||||
const outputDir = options.o || options.output || ''
|
||||
fileNames.forEach((inputFileName) => {
|
||||
gen(inputFileName, outputDir)
|
||||
})
|
||||
return
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
async function gen(inputFileName, outputDir) {
|
||||
const docSpec = yaml.safeLoad(fs.readFileSync(inputFileName, 'utf8'))
|
||||
const defRef = fs.readFileSync(docSpec.info.definition, 'utf8')
|
||||
if (!defRef) return
|
||||
|
||||
const definition = JSON.parse(defRef)
|
||||
const id = docSpec.info.id
|
||||
const allLanguages = docSpec.info.libraries
|
||||
const pages = Object.entries(docSpec.pages).map(([name, x]: [string, OpenRef.Page]) => ({
|
||||
...x,
|
||||
pageName: name,
|
||||
}))
|
||||
|
||||
// Sidebar
|
||||
const inputFileNameToSnakeCase = inputFileName.replace('/', '_').replace('.yml', '')
|
||||
const sidebarFileName = `sidebar_${inputFileNameToSnakeCase}.js`
|
||||
const sidebar = generateSidebar(docSpec)
|
||||
await writeToDisk(sidebarFileName, sidebar)
|
||||
console.log('Sidebar created: ', sidebarFileName)
|
||||
|
||||
// Index Page
|
||||
const indexFilename = outputDir + `/index.mdx`
|
||||
const index = generateDocsIndexPage(docSpec, inputFileName)
|
||||
await writeToDisk(indexFilename, index)
|
||||
console.log('The index was saved: ', indexFilename)
|
||||
|
||||
// Generate Pages
|
||||
pages.forEach(async (pageSpec: OpenRef.Page) => {
|
||||
try {
|
||||
const slug = slugify(pageSpec.pageName)
|
||||
const hasTsRef = pageSpec['$ref'] || null
|
||||
const tsDefinition = hasTsRef && extractTsDocNode(hasTsRef, definition)
|
||||
if (hasTsRef && !tsDefinition) throw new Error('Definition not found: ' + hasTsRef)
|
||||
|
||||
const description =
|
||||
pageSpec.description || tsDocCommentToMdComment(getDescriptionFromDefintion(tsDefinition))
|
||||
|
||||
// Create page
|
||||
const content = Page({
|
||||
slug,
|
||||
id: slug,
|
||||
specFileName: inputFileName,
|
||||
title: pageSpec.title || pageSpec.pageName,
|
||||
description,
|
||||
parameters: hasTsRef ? generateParameters(tsDefinition) : '',
|
||||
spotlight: generateSpotlight(id, pageSpec['examples'] || [], allLanguages),
|
||||
examples: generateExamples(id, pageSpec['examples'] || [], allLanguages),
|
||||
notes: pageSpec.notes,
|
||||
})
|
||||
|
||||
// Write to disk
|
||||
const dest = outputDir + `/${slug}.mdx`
|
||||
await writeToDisk(dest, content)
|
||||
console.log('Saved: ', dest)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function generateParameters(tsDefinition: any) {
|
||||
let functionDeclaration = null
|
||||
if (tsDefinition.kindString == 'Method') {
|
||||
functionDeclaration = tsDefinition
|
||||
} else if (tsDefinition.kindString == 'Constructor') {
|
||||
functionDeclaration = tsDefinition
|
||||
} else functionDeclaration = tsDefinition?.type?.declaration
|
||||
if (!functionDeclaration) return ''
|
||||
|
||||
const paramDefinitions: TsDoc.TypeDefinition[] = functionDeclaration.signatures[0].parameters // PMC: seems flaky.. why the [0]?
|
||||
if (!paramDefinitions) return ''
|
||||
|
||||
// const paramsComments: TsDoc.CommentTag = tsDefinition.comment?.tags?.filter(x => x.tag == 'param')
|
||||
let parameters = paramDefinitions.map((x) => recurseThroughParams(x)).join(`\n`)
|
||||
return methodListGroup(parameters)
|
||||
}
|
||||
|
||||
function getDescriptionFromDefintion(tsDefinition) {
|
||||
if (!tsDefinition) return null
|
||||
if (['Method', 'Constructor', 'Constructor signature'].includes(tsDefinition.kindString))
|
||||
return tsDefinition?.signatures[0].comment
|
||||
else return tsDefinition?.comment || ''
|
||||
}
|
||||
|
||||
function recurseThroughParams(paramDefinition: TsDoc.TypeDefinition) {
|
||||
let children = paramDefinition.type?.declaration?.children
|
||||
const labelParams = {
|
||||
name: paramDefinition.name,
|
||||
isOptional: !!paramDefinition.flags.isOptional,
|
||||
type: extractParamTypeAsString(paramDefinition),
|
||||
description: paramDefinition.comment ? tsDocCommentToMdComment(paramDefinition.comment) : null,
|
||||
}
|
||||
let subContent = ''
|
||||
|
||||
if (!!children) {
|
||||
let properties = children
|
||||
.sort((a, b) => a.name.localeCompare(b.name)) // first alphabetical
|
||||
.sort((a, b) => (a.flags?.isOptional ? 1 : -1)) // required params first
|
||||
.map((x) => recurseThroughParams(x))
|
||||
let heading = `<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>`
|
||||
subContent = methodListGroup([heading].concat(properties).join('\n'))
|
||||
}
|
||||
|
||||
return methodListItemLabel(labelParams, subContent)
|
||||
}
|
||||
|
||||
const methodListGroup = (items) => `
|
||||
<ul className="method-list-group">
|
||||
${items}
|
||||
</ul>
|
||||
`
|
||||
|
||||
const methodListItemLabel = ({ name, isOptional, type, description }, subContent) => `
|
||||
<li className="method-list-item">
|
||||
<h4 className="method-list-item-label">
|
||||
<span className="method-list-item-label-name">
|
||||
${name}
|
||||
</span>
|
||||
<span className="method-list-item-label-badge ${!isOptional && 'required'}">
|
||||
${isOptional ? 'optional' : 'required'}
|
||||
</span>
|
||||
<span className="method-list-item-validation">
|
||||
${type}
|
||||
</span>
|
||||
</h4>
|
||||
<div class="method-list-item-description">
|
||||
|
||||
${description ? description : 'No description provided. '}
|
||||
|
||||
</div>
|
||||
${subContent}
|
||||
</li>
|
||||
`
|
||||
|
||||
function generateExamples(id: string, specExamples: any, allLanguages: any) {
|
||||
return specExamples.map((example) => {
|
||||
let allTabs = example.hideCodeBlock
|
||||
? ''
|
||||
: Tabs(id, allLanguages, generateTabs(allLanguages, example))
|
||||
return Example({ name: example.name, description: example.description, tabs: allTabs })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* A spotlight is an example which appears at the top of the page.
|
||||
*/
|
||||
function generateSpotlight(id: string, specExamples: any, allLanguages: any) {
|
||||
const spotlight = specExamples.find((x) => x.isSpotlight) || null
|
||||
const spotlightContent = !spotlight
|
||||
? ''
|
||||
: Tabs(id, allLanguages, generateTabs(allLanguages, spotlight))
|
||||
return spotlightContent
|
||||
}
|
||||
|
||||
function generateTabs(allLanguages: any, example: any) {
|
||||
return allLanguages
|
||||
.map((library) => {
|
||||
let content = example[library.id] || notImplemented
|
||||
return Tab(library.id, content)
|
||||
})
|
||||
.join('\n')
|
||||
}
|
||||
|
||||
const notImplemented = `
|
||||
\`\`\`
|
||||
Not yet implemented
|
||||
\`\`\`
|
||||
`
|
||||
|
||||
function extractParamTypeAsString(paramDefinition) {
|
||||
if (paramDefinition.type?.name) {
|
||||
return `<code>${paramDefinition.type.name}</code>`
|
||||
}
|
||||
if (paramDefinition.type?.type == 'union') {
|
||||
return paramDefinition.type.types
|
||||
.map((x) =>
|
||||
x.value
|
||||
? `<code>${x.value}</code>`
|
||||
: x.name
|
||||
? `<code>${x.name}</code>`
|
||||
: x.type
|
||||
? `<code>${x.type}</code>`
|
||||
: ''
|
||||
)
|
||||
.join(' | ')
|
||||
} else {
|
||||
return '<code>object</code>'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the definition to find the correct definition.
|
||||
* You can pass it a deeply nested node using dot notation. eg: 'LoggedInUser.data.email'
|
||||
*/
|
||||
function extractTsDocNode(nodeToFind: string, definition: any) {
|
||||
const nodePath = nodeToFind.split('.')
|
||||
let i = 0
|
||||
let previousNode = definition
|
||||
let currentNode = definition
|
||||
while (i < nodePath.length) {
|
||||
previousNode = currentNode
|
||||
currentNode = previousNode.children.find((x) => x.name == nodePath[i]) || null
|
||||
if (currentNode == null) {
|
||||
console.log(`Cant find ${nodePath[i]} in ${previousNode.children.map((x) => '\n' + x.name)}`)
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
return currentNode
|
||||
}
|
||||
|
||||
function generateSidebar(docSpec: any) {
|
||||
let path = docSpec.info.docs.path || ''
|
||||
let categories = docSpec.info.docs.sidebar.map((x) => {
|
||||
const items = x.items.map((item) => {
|
||||
let slug = slugify(item)
|
||||
return `'${path}${slug}'`
|
||||
})
|
||||
return SidebarCategory(x.name, items)
|
||||
})
|
||||
return Sidebar(categories)
|
||||
}
|
||||
|
||||
function generateDocsIndexPage(docSpec: any, inputFileName: string) {
|
||||
return Page({
|
||||
slug: slugify(docSpec.info.title),
|
||||
id: 'index',
|
||||
title: docSpec.info.title,
|
||||
specFileName: inputFileName,
|
||||
description: docSpec.info.description,
|
||||
})
|
||||
}
|
||||
|
||||
// Run everything
|
||||
const argv = require('minimist')(process.argv.slice(2))
|
||||
main(argv['_'], argv)
|
||||
@@ -1,9 +1,3 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
module.exports = {
|
||||
title: 'Supabase',
|
||||
tagline: 'Build in a weekend. Scale to millions.',
|
||||
@@ -169,7 +163,6 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
],
|
||||
scripts: [{ src: '/scripts/telemetry.js' }],
|
||||
plugins: [
|
||||
// [
|
||||
// '@docusaurus/plugin-content-docs',
|
||||
|
||||
+1
-12
@@ -1,11 +1,3 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
|
||||
module.exports = {
|
||||
docs: [
|
||||
{
|
||||
@@ -18,10 +10,7 @@ module.exports = {
|
||||
type: 'category',
|
||||
label: 'See Also',
|
||||
collapsed: false,
|
||||
items: [
|
||||
'handbook/contributing',
|
||||
'handbook/supasquad',
|
||||
],
|
||||
items: ['handbook/contributing', 'handbook/supasquad'],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
require('dotenv').config()
|
||||
var axios = require('axios')
|
||||
var fs = require('fs')
|
||||
|
||||
const query = `
|
||||
query BIO_QUERY($username: String!) {
|
||||
organization(login: $username) {
|
||||
id
|
||||
sponsorshipsAsMaintainer(first: 100) {
|
||||
totalCount
|
||||
nodes {
|
||||
createdAt
|
||||
privacyLevel
|
||||
tier {
|
||||
name
|
||||
}
|
||||
sponsor {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const fetchAllSponsors = async () => {
|
||||
const { data } = await axios.post(
|
||||
`https://api.github.com/graphql`,
|
||||
{
|
||||
query,
|
||||
variables: {
|
||||
username: 'supabase',
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `token ${process.env.GITHUB_SPONSORS_TOKEN}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
return data.data.organization.sponsorshipsAsMaintainer
|
||||
}
|
||||
|
||||
const formatResults = (graphqlResponse) => {
|
||||
return graphqlResponse.nodes
|
||||
.filter((x) => !!x.sponsor)
|
||||
.map((x) => ({
|
||||
tier: x.tier.name,
|
||||
sponsor: x.sponsor.login,
|
||||
}))
|
||||
}
|
||||
|
||||
const writeFile = (data) => {
|
||||
fs.writeFile(
|
||||
'./src/data/sponsors.json',
|
||||
JSON.stringify(data, null, 2),
|
||||
'utf8',
|
||||
function (err) {
|
||||
if (err) throw err
|
||||
console.log('sponsors.json saved.')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
const sponsorsResponse = await fetchAllSponsors()
|
||||
const formatted = formatResults(sponsorsResponse)
|
||||
writeFile(formatted)
|
||||
}
|
||||
main()
|
||||
@@ -1,10 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function Collapsable({ title, children }) {
|
||||
return (
|
||||
<details className="Collapsable">
|
||||
<summary>{title}</summary>
|
||||
<div>{children}</div>
|
||||
</details>
|
||||
)
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import React, { useState } from 'react'
|
||||
import CodeBlock from '@theme/CodeBlock'
|
||||
|
||||
export default function CustomCodeBlock({
|
||||
header,
|
||||
code,
|
||||
highlight,
|
||||
js,
|
||||
jsHighlight,
|
||||
response,
|
||||
language,
|
||||
}) {
|
||||
const [showResponse, toggleResponse] = useState(false)
|
||||
|
||||
let wrapperClass = ''
|
||||
if (header) wrapperClass += ' code-with-header'
|
||||
if (response) wrapperClass += ' code-with-response'
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={wrapperClass}>
|
||||
{header && <div className="code-header">{header}</div>}
|
||||
<>
|
||||
{code && (
|
||||
<CodeBlock className={language || 'bash'} metastring={highlight}>
|
||||
{code}
|
||||
</CodeBlock>
|
||||
)}
|
||||
{js && <CodeBlock metastring={jsHighlight}>{js}</CodeBlock>}
|
||||
</>
|
||||
</div>
|
||||
{response && (
|
||||
<>
|
||||
<div className={'code-with-header repsonse-header'}>
|
||||
<a
|
||||
className="code-header has-hover-pointer"
|
||||
style={showResponse ? styles.responseShown : styles.responseHidden}
|
||||
onClick={() => toggleResponse(!showResponse)}
|
||||
>
|
||||
{showResponse ? 'Hide' : 'Show'} Response
|
||||
</a>
|
||||
{showResponse && <CodeBlock>{response}</CodeBlock>}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = {
|
||||
responseShown: {
|
||||
textAlign: 'right',
|
||||
display: 'block',
|
||||
borderRadius: '0',
|
||||
color: 'var(--custom-primary)',
|
||||
borderTop: '1px solid #444',
|
||||
},
|
||||
responseHidden: {
|
||||
textAlign: 'right',
|
||||
display: 'block',
|
||||
borderBottom: 'none',
|
||||
borderRadius: '0 0 4px 4px',
|
||||
borderTop: '1px solid #444',
|
||||
color: '#ccc',
|
||||
},
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
import React, { useState } from 'react'
|
||||
import extensions from '../data/extensions.json'
|
||||
|
||||
export default function Extensions() {
|
||||
const [filter, setFilter] = useState('')
|
||||
return (
|
||||
<>
|
||||
<div style={styles.inputContainer}>
|
||||
<input
|
||||
type="text"
|
||||
style={styles.input}
|
||||
placeholder="Filter"
|
||||
onChange={(e) => setFilter(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="row" style={styles.row}>
|
||||
{extensions
|
||||
.filter((x) => x.name.indexOf(filter) >= 0)
|
||||
.map((extension) => (
|
||||
<div className={'col col--6'} key={extension.name} style={styles.column}>
|
||||
<div style={styles.card}>
|
||||
<h3>
|
||||
<code style={styles.title}>{extension.name}</code>
|
||||
</h3>
|
||||
<p style={styles.description}>
|
||||
{extension.comment.charAt(0).toUpperCase() + extension.comment.slice(1)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = {
|
||||
inputContainer: {
|
||||
marginBottom: '15px',
|
||||
},
|
||||
input: {
|
||||
border: '1px solid var(--ifm-panel-border-color)',
|
||||
borderRadius: 4,
|
||||
backgroundColor: 'var(--custom-background-color-diff)',
|
||||
color: 'var(--ifm-font-color-base)',
|
||||
margin: 0,
|
||||
padding: '6px 8px',
|
||||
width: 300,
|
||||
},
|
||||
column: {
|
||||
margin: '5px 0px',
|
||||
padding: '0px 5px',
|
||||
},
|
||||
card: {
|
||||
border: '1px solid var(--ifm-panel-border-color)',
|
||||
borderRadius: 5,
|
||||
padding: 8,
|
||||
},
|
||||
title: {
|
||||
margin: 0,
|
||||
fontSize: '0.9rem',
|
||||
border: '1px solid var(--ifm-panel-border-color)',
|
||||
},
|
||||
description: {
|
||||
fontSize: '0.8rem',
|
||||
margin: 0,
|
||||
},
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function Figure({ src, alt, caption }) {
|
||||
return (
|
||||
<div className="Figure">
|
||||
<figure>
|
||||
<img src={src} alt={alt} />
|
||||
<figcaption>{caption}</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function GithubCard({ title, description, href, stars, handle }) {
|
||||
return (
|
||||
<a className={'card'} href={href} style={{ height: '100%' }}>
|
||||
<div className="card__body">
|
||||
<h4 style={styles.h4} style={{ margin: 0 }}>
|
||||
{title.toUpperCase()}
|
||||
</h4>
|
||||
<small>{description}</small>
|
||||
</div>
|
||||
<hr style={styles.hr} />
|
||||
<div style={styles.cardBase}>
|
||||
<div>@{handle}</div>
|
||||
<div>{stars} ★</div>
|
||||
</div>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = {
|
||||
hr: {
|
||||
margin: '15px 0 10px 0',
|
||||
},
|
||||
h3: {
|
||||
margin: 0,
|
||||
textTransform: 'capitalize',
|
||||
},
|
||||
cardBase: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
padding: '0 15px 10px 15px',
|
||||
fontSize: '0.8em',
|
||||
},
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function HowCard({ title, description, featureTitle, features }) {
|
||||
return (
|
||||
<div className={'HowCard'}>
|
||||
<div className={'card'} style={styles.card}>
|
||||
<h4 style={styles.h4}>{title}</h4>
|
||||
<div className="card__body" style={styles.cardBase}>
|
||||
{description}
|
||||
<h5 style={styles.h5}>{featureTitle}</h5>
|
||||
<div style={styles.features}>
|
||||
{features.map((x, i) => (
|
||||
<div key={i}>
|
||||
<span>
|
||||
<img src="/img/check.svg" alt="✔" style={styles.check} />
|
||||
</span>
|
||||
<span>{x}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = {
|
||||
h4: {
|
||||
padding: 10,
|
||||
textAlign: 'center',
|
||||
borderBottom: '1px solid #000',
|
||||
margin: 0,
|
||||
},
|
||||
h5: {
|
||||
textTransform: 'uppercase',
|
||||
// opacity: 0.5,
|
||||
margin: '10px 0 0px 0',
|
||||
fontSize: '0.9em',
|
||||
},
|
||||
card: {
|
||||
border: '1px solid #000',
|
||||
boxShadow: 'none',
|
||||
},
|
||||
cardBase: {
|
||||
fontSize: '0.9em',
|
||||
},
|
||||
check: {
|
||||
width: 10,
|
||||
height: 10,
|
||||
marginRight: 10,
|
||||
},
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import mermaid from 'mermaid'
|
||||
|
||||
const theme = `
|
||||
.node rect { fill: rgba(62,207,142, 0.3); stroke: #24b47e; }
|
||||
.cluster rect { fill: var(--custom-background-color-highlight); stroke: #999; }
|
||||
.edgePath path { fill: var(--custom-primary) }
|
||||
.edgePath .path { stroke: var(--custom-primary) }
|
||||
|
||||
g.classGroup rect { fill: rgba(62,207,142, 0.3); stroke: #24b47e; }
|
||||
g.classGroup line { stroke: var(--custom-primary); }
|
||||
g.classGroup text { fill: var(--ifm-color-content); color: var(--ifm-color-content); }
|
||||
.classLabel .label { fill: var(--ifm-color-content); color: var(--ifm-color-content); }
|
||||
classGroup .title { fill: var(--ifm-color-content); color: var(--ifm-color-content); }
|
||||
composition { stroke: var(--custom-primary); }
|
||||
aggregation { stroke: var(--custom-primary); }
|
||||
dependency { stroke: var(--custom-primary); }
|
||||
.relation { stroke: var(--custom-primary); }
|
||||
`
|
||||
|
||||
mermaid.initialize({ themeCSS: theme })
|
||||
|
||||
export default function Mermaid({ graph, classNames, caption }) {
|
||||
let [rendered, setRendered] = useState(<div></div>)
|
||||
|
||||
useEffect(() => {
|
||||
mermaid.render('mermaid-ID', graph.toString(), (html) => setRendered(html))
|
||||
}, [graph])
|
||||
|
||||
return (
|
||||
<div className={`Mermaid ${classNames || ''}`}>
|
||||
{caption && <figcaption>{caption}</figcaption>}
|
||||
<div className="graph" dangerouslySetInnerHTML={{ __html: rendered }}></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
import React, { useRef, useEffect } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default function Section({ title, id, style, children }) {
|
||||
const hash = String(id ? id : title)
|
||||
.trim()
|
||||
.replace(/\s/g, '-')
|
||||
.toLowerCase()
|
||||
const sectionRef = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
function scrollOnHash() {
|
||||
const clearedLocationHash = window.location.hash.substring(1)
|
||||
|
||||
if (clearedLocationHash == hash) {
|
||||
sectionRef.current.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
|
||||
function changeHash() {
|
||||
const el = document.getElementById(hash)
|
||||
|
||||
if (el) {
|
||||
const elementPos = el.getBoundingClientRect()
|
||||
|
||||
if (elementPos.top <= 80 && elementPos.top >= 0) replaceHistoryHash()
|
||||
}
|
||||
}
|
||||
scrollOnHash()
|
||||
window.addEventListener('scroll', changeHash)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', changeHash)
|
||||
}
|
||||
}, [])
|
||||
|
||||
function replaceHistoryHash() {
|
||||
history.replaceState(history.state, '', `#${hash}`)
|
||||
}
|
||||
|
||||
function handleHashClick() {
|
||||
replaceHistoryHash()
|
||||
sectionRef.current.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="section-lg">
|
||||
<div className="container Section">
|
||||
<h2
|
||||
className={`${stylePropOptions[style]} Section-Title`}
|
||||
ref={sectionRef}
|
||||
onClick={handleHashClick}
|
||||
id={hash}
|
||||
>
|
||||
{title}
|
||||
<span className="Section-Hash">#</span>
|
||||
</h2>
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
const stylePropOptions = {
|
||||
underline: 'with-underline',
|
||||
}
|
||||
|
||||
Section.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
style: PropTypes.oneOf(['underline']),
|
||||
}
|
||||
+6
-293
@@ -33,9 +33,9 @@
|
||||
/*
|
||||
Customization here for both Light and Dark themes
|
||||
*/
|
||||
--custom-font-base: 'Inter', BlinkMacSystemFont, -apple-system, 'Segoe UI', 'Roboto',
|
||||
'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Helvetica',
|
||||
'Arial', sans-serif;
|
||||
--custom-font-base: 'Inter', BlinkMacSystemFont, -apple-system, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Helvetica', 'Arial',
|
||||
sans-serif;
|
||||
--custom-font-code: 'office code pro', Menlo, monospace;
|
||||
--custom-font-size-base: 1rem;
|
||||
--custom-border-radius: 3px;
|
||||
@@ -236,7 +236,9 @@ body {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h4, h5, h6 {
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
@@ -652,20 +654,6 @@ div[class^='sidebar_'] .menu__link.menu__link--active:not(.menu__link--sublist)
|
||||
}
|
||||
}
|
||||
|
||||
.DummyData {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.DummyData div {
|
||||
padding-right: 30px;
|
||||
}
|
||||
.Collapsable summary {
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.Collapsable summary:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div[class^='codeBlockContent'],
|
||||
div[class*=' codeBlockContent'],
|
||||
.prism-code {
|
||||
@@ -804,49 +792,6 @@ a.hash-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.HowSections .col {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.HowSections img.diagram {
|
||||
margin: 0px auto 30px auto;
|
||||
display: block;
|
||||
}
|
||||
.HowCard {
|
||||
position: relative;
|
||||
}
|
||||
.HowCard::before,
|
||||
.HowCard::after {
|
||||
bottom: 100%;
|
||||
border: solid transparent;
|
||||
content: '';
|
||||
height: 0;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.HowCard::before {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
|
||||
border-bottom: 5px solid black;
|
||||
border-width: 12px;
|
||||
margin-left: -12px;
|
||||
}
|
||||
.HowCard::after {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
|
||||
border-bottom: 5px solid var(--ifm-card-background-color);
|
||||
border-width: 11px;
|
||||
margin-left: -11px;
|
||||
}
|
||||
|
||||
.Blog .code-with-header {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
@@ -854,46 +799,6 @@ a.hash-link {
|
||||
color: var(--ifm-color-content);
|
||||
}
|
||||
|
||||
.Figure {
|
||||
text-align: center;
|
||||
margin: 30px 0;
|
||||
}
|
||||
.Figure figure {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
.Figure img {
|
||||
box-shadow: 0px 0px 5px 5px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.Figure figcaption {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.Mermaid {
|
||||
text-align: center;
|
||||
margin: 80px 0;
|
||||
font-family: var(--custom-font-base);
|
||||
color: var(--ifm-color-content);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.Mermaid .graph {
|
||||
overflow-x: auto;
|
||||
margin: 0px calc(var(--ifm-spacing-horizontal) * -1);
|
||||
padding: var(--ifm-spacing-horizontal);
|
||||
}
|
||||
.Mermaid div,
|
||||
.Mermaid tspan,
|
||||
.Mermaid g.classGroup text {
|
||||
font-family: var(--custom-font-base);
|
||||
color: var(--ifm-color-content);
|
||||
/* font-size: 0.9em; */
|
||||
}
|
||||
.Mermaid figcaption {
|
||||
font-size: 0.8rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.DocSearch-Button {
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
@@ -1075,198 +980,6 @@ html[data-theme='dark'] .navbar-item-twitter:before {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Section */
|
||||
.Section {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.Section-Hash {
|
||||
margin-left: 8px;
|
||||
color: var(--custom-content-color-light);
|
||||
opacity: 0.4;
|
||||
}
|
||||
.Section-Title:hover .Section-Hash {
|
||||
color: var(--custom-primary);
|
||||
opacity: 1;
|
||||
}
|
||||
.Section-Title {
|
||||
cursor: pointer;
|
||||
scroll-margin: 74px; /* Navbar size (60) + a little margin */
|
||||
}
|
||||
|
||||
/* Showcase */
|
||||
.ShowcaseCard {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: none;
|
||||
border: 1px solid #333;
|
||||
padding: var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing);
|
||||
}
|
||||
|
||||
.ShowcaseCard:hover {
|
||||
transition: all 0.2s ease;
|
||||
border: 1px solid var(--custom-primary);
|
||||
box-shadow: var(--custom-shadow-xl), 0 0 0 1px var(--custom-primary) !important;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Img {
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.ShowcaseCard-ImgContainer {
|
||||
height: 140px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Text {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Text p {
|
||||
width: 100%;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Text h3 {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
backdrop-filter: blur(3px) contrast(80%);
|
||||
padding: var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing);
|
||||
transition: 0.2s ease;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: var(--ifm-card-vertical-spacing);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ShowcaseCard:hover h3 {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Tag {
|
||||
color: var(--custom-primary);
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
margin: 8px 4px 12px 0px;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Footer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Footer-Item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Spaces between children */
|
||||
.ShowcaseCard-Footer-Spaced .ShowcaseCard-Footer-Item:first-child {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Footer-Spaced .ShowcaseCard-Footer-Item:nth-child(even) {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Footer-Spaced .ShowcaseCard-Footer-Item:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 997px) {
|
||||
.ShowcaseCard-ImgContainer {
|
||||
height: 120px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Text {
|
||||
width: 100%;
|
||||
margin-left: var(--ifm-card-horizontal-spacing);
|
||||
}
|
||||
|
||||
.ShowcaseCard-Tag {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Footer a {
|
||||
margin: var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing) 0 0;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Text h3 {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
opacity: 1;
|
||||
backdrop-filter: blur(0) contrast(100%);
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
.ShowcaseCard-ImgContainer {
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
.ShowcaseCard-Content {
|
||||
flex-direction: column;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Text {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Text h3 {
|
||||
margin-top: var(--ifm-card-vertical-spacing);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 380px) {
|
||||
.ShowcaseCard-Footer {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Spaces between children */
|
||||
.ShowcaseCard-Footer-Spaced .ShowcaseCard-Footer-Item:first-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.ShowcaseCard-Footer-Spaced .ShowcaseCard-Footer-Item:nth-child(even) {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
/* New CSS */
|
||||
|
||||
code {
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* CSS files with the .module.css suffix will be treated as CSS modules
|
||||
* and scoped locally.
|
||||
|
||||
Reference in new issue
Block a user