Merge pull request #5326 from yangshun/yangshun/about-cleanup

chore(about): clean up unused files
This commit is contained in:
Isaiah Hamilton authored and GitHub committed 2022-02-17 23:30:11 -05:00
commit 3c0e403263
15 files changed
+7 -1013

No files matched your search

-5
View File
@@ -1,8 +1,3 @@
node_modules
build
.docusaurus
docs/client
docs/gotrue/client
docs/postgrest/client
docs/realtime/client
docs/reference
-268
View File
@@ -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)
-7
View File
@@ -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
View File
@@ -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'],
},
],
}
-71
View File
@@ -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()
-10
View File
@@ -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>
)
}
-66
View File
@@ -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',
},
}
-67
View File
@@ -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,
},
}
-12
View File
@@ -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>
)
}
-36
View File
@@ -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',
},
}
-52
View File
@@ -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,
},
}
-36
View File
@@ -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>
)
}
-71
View File
@@ -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
View File
@@ -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 {
-7
View File
@@ -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.