Compare commits
95 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
047af45cc1 | |
![]() |
355b3d2c9c | |
![]() |
7140fac0af | |
![]() |
6a060c9b11 | |
![]() |
10c3a80a7d | |
![]() |
fc82cc962f | |
![]() |
daec71f7eb | |
![]() |
bb944efb16 | |
![]() |
b55dc1864d | |
![]() |
db6659ce4b | |
![]() |
432b0c1aec | |
![]() |
75e9f4cb04 | |
![]() |
5fc0aea585 | |
![]() |
748a31a0b6 | |
![]() |
0b71235389 | |
![]() |
8b0f41bcd1 | |
![]() |
a31a06cd72 | |
![]() |
b45ec9c8d1 | |
![]() |
c0253b5498 | |
![]() |
1e78cca1d3 | |
![]() |
251d8df336 | |
![]() |
8a7d4baca8 | |
![]() |
8becc53ddf | |
![]() |
a2a136a336 | |
![]() |
3835908542 | |
![]() |
c6e865bec1 | |
![]() |
5fa1fc7a1f | |
![]() |
07ee4ebd90 | |
![]() |
60b7cb9614 | |
![]() |
1ae52f0ebd | |
![]() |
18856cc719 | |
![]() |
7317a3e14d | |
![]() |
fefe1bd93a | |
![]() |
954c3fb1d1 | |
![]() |
69b1633af8 | |
![]() |
790228f9e4 | |
![]() |
d330a80e60 | |
![]() |
68fd241829 | |
![]() |
2e54e4461f | |
![]() |
c70db6153b | |
![]() |
a8808f2e1c | |
![]() |
d3382d172a | |
![]() |
67b6b0e511 | |
![]() |
a6df4bf396 | |
![]() |
7bf7e41d7f | |
![]() |
a41f4ddc5e | |
![]() |
ba5552830e | |
![]() |
3fe2f7aff0 | |
![]() |
a96ed745cc | |
![]() |
53436c2c03 | |
![]() |
44471af96e | |
![]() |
7ee80fd923 | |
![]() |
c51568fdde | |
![]() |
307d5c179b | |
![]() |
eb0024c8cc | |
![]() |
516c1068a3 | |
![]() |
2039105c88 | |
![]() |
cf35548edf | |
![]() |
fb4a28c068 | |
![]() |
c17ea4234c | |
![]() |
b54537cd34 | |
![]() |
3da9ad26c5 | |
![]() |
0168a343d3 | |
![]() |
c2dafa17c4 | |
![]() |
8c839138f6 | |
![]() |
6c65d64b81 | |
![]() |
bd2805b23b | |
![]() |
10ef97a4d4 | |
![]() |
cbe5ed9386 | |
![]() |
f738ca5cf5 | |
![]() |
5947a1ba42 | |
![]() |
05941739bf | |
![]() |
b25fe0cefb | |
![]() |
54bec393bf | |
![]() |
7a0d228f77 | |
![]() |
4e81ebe622 | |
![]() |
83cf8ed165 | |
![]() |
f0d9ab32bb | |
![]() |
c46fcc9db8 | |
![]() |
e22906afa4 | |
![]() |
b7d31ddb0c | |
![]() |
f731691cd1 | |
![]() |
11cde0b638 | |
![]() |
fc5df403af | |
![]() |
4e4613d8ab | |
![]() |
24bbf0788b | |
![]() |
35463b9631 | |
![]() |
f194c394d2 | |
![]() |
592e934fe8 | |
![]() |
c30f034cf2 | |
![]() |
4193e13c7c | |
![]() |
14ed79b7b9 | |
![]() |
acbfdbb89d | |
![]() |
2261b9915a | |
![]() |
dbed0cb27d |
|
@ -1,6 +1,8 @@
|
||||||
**/node_modules
|
**/node_modules
|
||||||
**/public
|
**/public
|
||||||
**/build
|
**/build
|
||||||
|
**/dist
|
||||||
**/config
|
**/config
|
||||||
**/scripts
|
**/scripts
|
||||||
|
**/docs
|
||||||
**/playground
|
**/playground
|
||||||
|
|
14
.eslintrc
14
.eslintrc
|
@ -25,6 +25,20 @@
|
||||||
"globals": {
|
"globals": {
|
||||||
"strapi": true
|
"strapi": true
|
||||||
},
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"**/*.cy.*",
|
||||||
|
"./cypress/**/*.*"
|
||||||
|
],
|
||||||
|
"extends": [
|
||||||
|
"plugin:cypress/recommended"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"project": "./tsconfig.cypress.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"import/no-unresolved": [2, {
|
"import/no-unresolved": [2, {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
name: Deploy Docs
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
name: Deploy
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment:
|
||||||
|
name: docs.pluginpal.io
|
||||||
|
url: https://docs.pluginpal.io/config-sync
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Docker
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '14'
|
||||||
|
|
||||||
|
- name: Build a Docker image
|
||||||
|
run: |
|
||||||
|
cd docs
|
||||||
|
docker build \
|
||||||
|
-t docs-config-sync:latest .
|
||||||
|
docker save -o ../docs-config-sync-latest.tar docs-config-sync:latest
|
||||||
|
|
||||||
|
- name: Transfer the Docker image to the Dokku server
|
||||||
|
uses: appleboy/scp-action@v0.1.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SSH_HOST }}
|
||||||
|
username: ${{ secrets.SSH_CI_USERNAME }}
|
||||||
|
password: ${{ secrets.SSH_CI_PASSWORD }}
|
||||||
|
source: docs-config-sync-latest.tar
|
||||||
|
target: /var/lib/dokku/data/storage/docs/docker-images
|
||||||
|
|
||||||
|
- name: Deploy the Dokku app based on the Docker image
|
||||||
|
uses: appleboy/ssh-action@v0.1.10
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SSH_HOST }}
|
||||||
|
username: ${{ secrets.SSH_CI_USERNAME }}
|
||||||
|
password: ${{ secrets.SSH_CI_PASSWORD }}
|
||||||
|
script_stop: true
|
||||||
|
script: |
|
||||||
|
sudo docker load -i /var/lib/dokku/data/storage/docs/docker-images/docs-config-sync-latest.tar
|
||||||
|
DOCS_CONFIG_SYNC_LATEST_IMAGE=$(sudo docker images --format "{{.ID}}" docs-config-sync:latest)
|
||||||
|
sudo docker tag docs-config-sync:latest docs-config-sync:$DOCS_CONFIG_SYNC_LATEST_IMAGE
|
||||||
|
dokku git:from-image docs-config-sync docs-config-sync:$DOCS_CONFIG_SYNC_LATEST_IMAGE
|
||||||
|
sudo docker system prune --all --force
|
|
@ -7,9 +7,9 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
always-auth: true
|
always-auth: true
|
||||||
node-version: 18
|
node-version: 18
|
||||||
|
@ -21,11 +21,30 @@ jobs:
|
||||||
run: yarn build
|
run: yarn build
|
||||||
- name: Get the release tag version
|
- name: Get the release tag version
|
||||||
id: get_version
|
id: get_version
|
||||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
|
||||||
|
- name: Extract pre-release tag if any
|
||||||
|
id: extract_tag
|
||||||
|
run: |
|
||||||
|
VERSION="${{ steps.get_version.outputs.VERSION }}"
|
||||||
|
if [[ $VERSION == *-* ]]; then
|
||||||
|
# Extract everything between hyphen and last period (or end of string)
|
||||||
|
PRETAG=$(echo $VERSION | sed -E 's/.*-([^.]+).*/\1/')
|
||||||
|
echo "IS_PRERELEASE=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "NPM_TAG=$PRETAG" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "IS_PRERELEASE=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "NPM_TAG=latest" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
- name: Get source branch
|
||||||
|
id: get_branch
|
||||||
|
run: |
|
||||||
|
RELEASE_COMMIT=$(git rev-list -n 1 ${{ steps.get_version.outputs.VERSION }})
|
||||||
|
SOURCE_BRANCH=$(git branch -r --contains $RELEASE_COMMIT | grep -v HEAD | head -n 1 | sed 's/.*origin\///')
|
||||||
|
echo "SOURCE_BRANCH=$SOURCE_BRANCH" >> $GITHUB_OUTPUT
|
||||||
- name: Set package version
|
- name: Set package version
|
||||||
run: yarn version --new-version "${{ steps.get_version.outputs.VERSION }}" --no-git-tag-version
|
run: yarn version --new-version "${{ steps.get_version.outputs.VERSION }}" --no-git-tag-version
|
||||||
- name: Publish package
|
- name: Publish package
|
||||||
run: yarn publish --access public
|
run: yarn publish --access public --tag ${{ steps.extract_tag.outputs.NPM_TAG }}
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
- name: Push version bump
|
- name: Push version bump
|
||||||
|
|
|
@ -18,8 +18,8 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
node: [18, 20]
|
node: [18, 20]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: 'yarn'
|
cache: 'yarn'
|
||||||
|
@ -27,16 +27,16 @@ jobs:
|
||||||
run: yarn --frozen-lockfile
|
run: yarn --frozen-lockfile
|
||||||
- name: Run eslint
|
- name: Run eslint
|
||||||
run: yarn run eslint
|
run: yarn run eslint
|
||||||
integration:
|
test:
|
||||||
name: 'integration'
|
name: 'test'
|
||||||
needs: [lint]
|
needs: [lint]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node: [18, 20]
|
node: [18, 20]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: 'yarn'
|
cache: 'yarn'
|
||||||
|
@ -50,8 +50,26 @@ jobs:
|
||||||
run: cd playground && yarn install --unsafe-perm
|
run: cd playground && yarn install --unsafe-perm
|
||||||
- name: Build playground
|
- name: Build playground
|
||||||
run: yarn playground:build
|
run: yarn playground:build
|
||||||
- name: Run test
|
# - name: Run unit tests
|
||||||
|
# run: yarn test:unit
|
||||||
|
- name: Run integration tests
|
||||||
run: yarn run -s test:integration
|
run: yarn run -s test:integration
|
||||||
|
- name: Run end-to-end tests
|
||||||
|
uses: cypress-io/github-action@v6
|
||||||
|
with:
|
||||||
|
start: yarn playground:start
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: cypress-screenshots
|
||||||
|
path: cypress/screenshots
|
||||||
|
if-no-files-found: ignore # 'warn' or 'error' are also available, defaults to `warn`
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: cypress-videos
|
||||||
|
path: cypress/videos
|
||||||
|
if-no-files-found: ignore # 'warn' or 'error' are also available, defaults to `warn`
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v2
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
|
@ -59,20 +77,3 @@ jobs:
|
||||||
flags: unit
|
flags: unit
|
||||||
verbose: true
|
verbose: true
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
# unit:
|
|
||||||
# name: 'unit'
|
|
||||||
# needs: [lint]
|
|
||||||
# runs-on: ubuntu-latest
|
|
||||||
# strategy:
|
|
||||||
# matrix:
|
|
||||||
# node: [16, 18, 20]
|
|
||||||
# steps:
|
|
||||||
# - uses: actions/checkout@v2
|
|
||||||
# - uses: actions/setup-node@v2
|
|
||||||
# with:
|
|
||||||
# node-version: ${{ matrix.node }}
|
|
||||||
# cache: 'yarn'
|
|
||||||
# - name: Install dependencies
|
|
||||||
# run: yarn --ignore-scripts --frozen-lockfile
|
|
||||||
# - name: Run test
|
|
||||||
# run: yarn run -s test:unit
|
|
||||||
|
|
|
@ -14,3 +14,8 @@ npm-debug.log
|
||||||
build
|
build
|
||||||
dist
|
dist
|
||||||
bundle
|
bundle
|
||||||
|
|
||||||
|
# Cypress
|
||||||
|
cypress/screenshots/
|
||||||
|
cypress/videos/
|
||||||
|
cypress/downloads/
|
||||||
|
|
|
@ -1,7 +1,23 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer-continued';
|
import RDV, { DiffMethod } from 'react-diff-viewer-continued';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An issue with the diff-viewer library causes a difference in the way the library is exported.
|
||||||
|
* Depending on whether the library is loaded through the browser or through the server, the default export may or may not be present.
|
||||||
|
* This causes issues with SSR and the way the library is imported.
|
||||||
|
*
|
||||||
|
* Below a workaround to fix this issue.
|
||||||
|
*
|
||||||
|
* @see https://github.com/Aeolun/react-diff-viewer-continued/issues/43
|
||||||
|
*/
|
||||||
|
let ReactDiffViewer;
|
||||||
|
if (typeof RDV.default !== 'undefined') {
|
||||||
|
ReactDiffViewer = RDV.default;
|
||||||
|
} else {
|
||||||
|
ReactDiffViewer = RDV;
|
||||||
|
}
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Modal,
|
Modal,
|
||||||
Grid,
|
Grid,
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
// <reference types="cypress" />
|
||||||
|
|
||||||
|
describe('Config Sync', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.task('deleteFolder', 'playground/config/sync');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Check the config diff', () => {
|
||||||
|
cy.login();
|
||||||
|
cy.navigateToInterface();
|
||||||
|
cy.initialExport();
|
||||||
|
|
||||||
|
cy.makeConfigChanges();
|
||||||
|
|
||||||
|
cy.navigateToInterface();
|
||||||
|
|
||||||
|
cy.get('tbody tr').contains('plugin_users-permissions_advanced').click();
|
||||||
|
|
||||||
|
cy.contains('"unique_email": true,');
|
||||||
|
cy.contains('"unique_email": false,');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Download the config as zip', () => {
|
||||||
|
cy.login();
|
||||||
|
cy.navigateToInterface();
|
||||||
|
cy.initialExport();
|
||||||
|
|
||||||
|
cy.intercept({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/config-sync/zip',
|
||||||
|
}).as('getConfigZip');
|
||||||
|
|
||||||
|
cy.get('button').contains('Download Config').click();
|
||||||
|
|
||||||
|
cy.wait('@getConfigZip').then((interception) => {
|
||||||
|
const configZipResponse = interception.response.body;
|
||||||
|
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||||
|
cy.readFile(`${downloadsFolder}/${configZipResponse.name.replaceAll(':', '_')}`).should('exist');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Partial import & export', () => {
|
||||||
|
cy.login();
|
||||||
|
cy.navigateToInterface();
|
||||||
|
cy.initialExport();
|
||||||
|
|
||||||
|
cy.makeConfigChanges();
|
||||||
|
|
||||||
|
cy.navigateToInterface();
|
||||||
|
|
||||||
|
cy.get('button[aria-label="Select all entries"]').click();
|
||||||
|
|
||||||
|
cy.intercept({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/config-sync/import',
|
||||||
|
}).as('importConfig');
|
||||||
|
cy.get('button[aria-label="Select plugin_upload_settings"]').click();
|
||||||
|
cy.get('button').contains('Import').click();
|
||||||
|
cy.get('button').contains('Yes, import').click();
|
||||||
|
cy.wait('@importConfig').its('response.statusCode').should('equal', 200);
|
||||||
|
cy.contains('plugin_users-permissions_advanced');
|
||||||
|
cy.contains('plugin_users-permissions_email');
|
||||||
|
|
||||||
|
cy.intercept({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/config-sync/export',
|
||||||
|
}).as('exportConfig');
|
||||||
|
cy.get('button[aria-label="Select plugin_users-permissions_advanced"]').click();
|
||||||
|
cy.get('button').contains('Export').click();
|
||||||
|
cy.get('button').contains('Yes, export').click();
|
||||||
|
cy.wait('@exportConfig').its('response.statusCode').should('equal', 200);
|
||||||
|
cy.contains('plugin_users-permissions_email');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,33 @@
|
||||||
|
const { defineConfig } = require('cypress');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
|
module.exports = defineConfig({
|
||||||
|
e2e: {
|
||||||
|
baseUrl: 'http://localhost:1337',
|
||||||
|
specPattern: '**/*.cy.{js,ts,jsx,tsx}',
|
||||||
|
video: true,
|
||||||
|
defaultCommandTimeout: 30000,
|
||||||
|
requestTimeout: 30000,
|
||||||
|
setupNodeEvents(on, config) {
|
||||||
|
// implement node event listeners here.
|
||||||
|
// eslint-disable-next-line global-require
|
||||||
|
require('cypress-terminal-report/src/installLogsPrinter')(on);
|
||||||
|
|
||||||
|
on('task', {
|
||||||
|
deleteFolder(folderName) {
|
||||||
|
console.log(`deleting folder ${folderName}`);
|
||||||
|
|
||||||
|
return fs.remove(folderName)
|
||||||
|
.then(() => {
|
||||||
|
console.log(`folder ${folderName} deleted`);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(`error deleting folder ${folderName}`, err);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,129 @@
|
||||||
|
// <reference types="cypress" />
|
||||||
|
// ***********************************************
|
||||||
|
// This example commands.ts shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||||
|
//
|
||||||
|
|
||||||
|
Cypress.Commands.add('login', (path) => {
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.intercept({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/admin/users/me',
|
||||||
|
}).as('sessionCheck');
|
||||||
|
|
||||||
|
cy.intercept({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/admin/init',
|
||||||
|
}).as('adminInit');
|
||||||
|
|
||||||
|
// Wait for the initial request to complete.
|
||||||
|
cy.wait('@adminInit').its('response.statusCode').should('equal', 200);
|
||||||
|
|
||||||
|
// Wait for the form to render.
|
||||||
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
cy.get('body').then(($body) => {
|
||||||
|
// Login
|
||||||
|
if ($body.text().includes('Log in to your Strapi account')) {
|
||||||
|
cy.get('input[name="email"]').type('johndoe@example.com');
|
||||||
|
cy.get('input[name="password"]').type('Abc12345678');
|
||||||
|
cy.get('button[type="submit"]').click();
|
||||||
|
cy.wait('@sessionCheck').its('response.statusCode').should('equal', 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register
|
||||||
|
if ($body.text().includes('Credentials are only used to authenticate in Strapi')) {
|
||||||
|
cy.get('input[name="firstname"]').type('John');
|
||||||
|
cy.get('input[name="email"]').type('johndoe@example.com');
|
||||||
|
cy.get('input[name="password"]').type('Abc12345678');
|
||||||
|
cy.get('input[name="confirmPassword"]').type('Abc12345678');
|
||||||
|
cy.get('button[type="submit"]').click();
|
||||||
|
cy.wait('@sessionCheck').its('response.statusCode').should('equal', 200);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('navigateToInterface', (path) => {
|
||||||
|
cy.intercept({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/config-sync/diff',
|
||||||
|
}).as('getConfigDiff');
|
||||||
|
|
||||||
|
cy.get('a[href="/admin/settings"]').click();
|
||||||
|
cy.get('a[href="/admin/settings/config-sync"]').click();
|
||||||
|
|
||||||
|
cy.wait('@getConfigDiff').its('response.statusCode').should('equal', 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Cypress.Commands.add('initialExport', (path) => {
|
||||||
|
cy.intercept({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/config-sync/export',
|
||||||
|
}).as('exportConfig');
|
||||||
|
|
||||||
|
cy.get('button').contains('Make the initial export').click();
|
||||||
|
cy.get('button').contains('Yes, export').click();
|
||||||
|
|
||||||
|
cy.wait('@exportConfig').its('response.statusCode').should('equal', 200);
|
||||||
|
|
||||||
|
cy.contains('Config was successfully exported to config/sync/.');
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('makeConfigChanges', (path) => {
|
||||||
|
// Change a setting in the UP advanced settings
|
||||||
|
cy.intercept({
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/users-permissions/advanced',
|
||||||
|
}).as('saveUpAdvanced');
|
||||||
|
cy.get('a[href="/admin/settings/users-permissions/advanced-settings"]').click();
|
||||||
|
cy.get('input[name="unique_email"').click();
|
||||||
|
cy.get('button[type="submit"]').click();
|
||||||
|
cy.wait('@saveUpAdvanced').its('response.statusCode').should('equal', 200);
|
||||||
|
|
||||||
|
// Change a setting in the media library settings
|
||||||
|
cy.intercept({
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/upload/settings',
|
||||||
|
}).as('saveMediaLibrarySettings');
|
||||||
|
cy.get('a[href="/admin/settings/media-library"]').click();
|
||||||
|
cy.get('input[name="responsiveDimensions"').click();
|
||||||
|
cy.get('button[type="submit"]').click();
|
||||||
|
cy.wait('@saveMediaLibrarySettings').its('response.statusCode').should('equal', 200);
|
||||||
|
|
||||||
|
// Change a setting in the email templates
|
||||||
|
cy.intercept({
|
||||||
|
method: 'PUT',
|
||||||
|
url: '/users-permissions/email-templates',
|
||||||
|
}).as('saveUpEmailTemplates');
|
||||||
|
cy.get('a[href="/admin/settings/users-permissions/email-templates"]').click();
|
||||||
|
cy.get('tbody tr').contains('Reset password').click();
|
||||||
|
cy.get('input[name="options.response_email"]').clear();
|
||||||
|
cy.get('input[name="options.response_email"]').type(`${Math.random().toString(36).substring(2, 15)}@example.com`);
|
||||||
|
cy.get('button[type="submit"]').click();
|
||||||
|
cy.wait('@saveUpEmailTemplates').its('response.statusCode').should('equal', 200);
|
||||||
|
});
|
|
@ -0,0 +1,22 @@
|
||||||
|
// ***********************************************************
|
||||||
|
// This example support/e2e.ts is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import './commands';
|
||||||
|
|
||||||
|
require('cypress-terminal-report/src/installLogsCollector')();
|
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
|
@ -0,0 +1,13 @@
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: npm
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: daily
|
||||||
|
ignore:
|
||||||
|
- dependency-name: '\*'
|
||||||
|
update-types: ["version-update:semver-patch"]
|
||||||
|
groups:
|
||||||
|
strapi:
|
||||||
|
patterns:
|
||||||
|
- "@strapi/*"
|
|
@ -0,0 +1,52 @@
|
||||||
|
name: Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
name: Deploy
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment:
|
||||||
|
name: docs.pluginpal.io
|
||||||
|
url: https://docs.pluginpal.io
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Docker
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '14'
|
||||||
|
|
||||||
|
- name: Build a Docker image
|
||||||
|
run: |
|
||||||
|
docker build \
|
||||||
|
-t pluginpal-docs:latest .
|
||||||
|
docker save -o pluginpal-docs-latest.tar pluginpal-docs:latest
|
||||||
|
|
||||||
|
- name: Transfer the Docker image to the Dokku server
|
||||||
|
uses: appleboy/scp-action@v0.1.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SSH_HOST }}
|
||||||
|
username: ${{ secrets.SSH_CI_USERNAME }}
|
||||||
|
password: ${{ secrets.SSH_CI_PASSWORD }}
|
||||||
|
source: pluginpal-docs-latest.tar
|
||||||
|
target: /var/lib/dokku/data/storage/docs/docker-images
|
||||||
|
|
||||||
|
- name: Deploy the Dokku app based on the Docker image
|
||||||
|
uses: appleboy/ssh-action@v0.1.10
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SSH_HOST }}
|
||||||
|
username: ${{ secrets.SSH_CI_USERNAME }}
|
||||||
|
password: ${{ secrets.SSH_CI_PASSWORD }}
|
||||||
|
script_stop: true
|
||||||
|
script: |
|
||||||
|
sudo docker load -i /var/lib/dokku/data/storage/docs/docker-images/pluginpal-docs-latest.tar
|
||||||
|
DOCS_LATEST_IMAGE=$(sudo docker images --format "{{.ID}}" pluginpal-docs:latest)
|
||||||
|
sudo docker tag pluginpal-docs:latest pluginpal-docs:$DOCS_LATEST_IMAGE
|
||||||
|
dokku git:from-image docs pluginpal-docs:$DOCS_LATEST_IMAGE
|
||||||
|
sudo docker system prune --all --force
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Dependencies
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# Production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.docusaurus
|
||||||
|
.cache-loader
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.DS_Store
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
|
@ -0,0 +1,29 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
# Stage 1: Base image.
|
||||||
|
## Start with a base image containing NodeJS so we can build Docusaurus.
|
||||||
|
FROM node:18-alpine3.18 as base
|
||||||
|
## Disable colour output from yarn to make logs easier to read.
|
||||||
|
ENV FORCE_COLOR=0
|
||||||
|
## Enable corepack.
|
||||||
|
RUN corepack enable
|
||||||
|
## Set the working directory to `/opt/docusaurus`.
|
||||||
|
WORKDIR /opt/docusaurus
|
||||||
|
|
||||||
|
# Stage 2b: Production build mode.
|
||||||
|
FROM base as prod
|
||||||
|
## Set the working directory to `/opt/docusaurus`.
|
||||||
|
WORKDIR /opt/docusaurus
|
||||||
|
## Copy over the source code.
|
||||||
|
COPY . /opt/docusaurus/
|
||||||
|
## Install dependencies with `--immutable` to ensure reproducibility.
|
||||||
|
RUN yarn install
|
||||||
|
## Build the static site.
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
# Stage 3a: Serve with `docusaurus serve`.
|
||||||
|
FROM prod as serve
|
||||||
|
## Expose the port that Docusaurus will run on.
|
||||||
|
EXPOSE 3000
|
||||||
|
## Run the production server.
|
||||||
|
CMD ["yarn", "serve", "--host", "0.0.0.0", "--no-open"]
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Website
|
||||||
|
|
||||||
|
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
$ yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
### Local Development
|
||||||
|
|
||||||
|
```
|
||||||
|
$ yarn start
|
||||||
|
```
|
||||||
|
|
||||||
|
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
```
|
||||||
|
$ yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
|
Using SSH:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ USE_SSH=true yarn deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
Not using SSH:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ GIT_USER=<Your GitHub username> yarn deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||||
|
};
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
slug: first-blog-post
|
||||||
|
title: First Blog Post
|
||||||
|
authors: [slorber, yangshun]
|
||||||
|
tags: [hola, docusaurus]
|
||||||
|
---
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet...
|
||||||
|
|
||||||
|
<!-- truncate -->
|
||||||
|
|
||||||
|
...consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
slug: long-blog-post
|
||||||
|
title: Long Blog Post
|
||||||
|
authors: yangshun
|
||||||
|
tags: [hello, docusaurus]
|
||||||
|
---
|
||||||
|
|
||||||
|
This is the summary of a very long blog post,
|
||||||
|
|
||||||
|
Use a `<!--` `truncate` `-->` comment to limit blog post size in the list view.
|
||||||
|
|
||||||
|
<!-- truncate -->
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
slug: mdx-blog-post
|
||||||
|
title: MDX Blog Post
|
||||||
|
authors: [slorber]
|
||||||
|
tags: [docusaurus]
|
||||||
|
---
|
||||||
|
|
||||||
|
Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
|
||||||
|
Use the power of React to create interactive blog posts.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
{/* truncate */}
|
||||||
|
|
||||||
|
For example, use JSX to create an interactive button:
|
||||||
|
|
||||||
|
```js
|
||||||
|
<button onClick={() => alert('button clicked!')}>Click me!</button>
|
||||||
|
```
|
||||||
|
|
||||||
|
<button onClick={() => alert('button clicked!')}>Click me!</button>
|
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
slug: welcome
|
||||||
|
title: Welcome
|
||||||
|
authors: [slorber, yangshun]
|
||||||
|
tags: [facebook, hello, docusaurus]
|
||||||
|
---
|
||||||
|
|
||||||
|
[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog).
|
||||||
|
|
||||||
|
Here are a few tips you might find useful.
|
||||||
|
|
||||||
|
<!-- truncate -->
|
||||||
|
|
||||||
|
Simply add Markdown files (or folders) to the `blog` directory.
|
||||||
|
|
||||||
|
Regular blog authors can be added to `authors.yml`.
|
||||||
|
|
||||||
|
The blog post date can be extracted from filenames, such as:
|
||||||
|
|
||||||
|
- `2019-05-30-welcome.md`
|
||||||
|
- `2019-05-30-welcome/index.md`
|
||||||
|
|
||||||
|
A blog post folder can be convenient to co-locate blog post images:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The blog supports tags as well!
|
||||||
|
|
||||||
|
**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config.
|
|
@ -0,0 +1,23 @@
|
||||||
|
yangshun:
|
||||||
|
name: Yangshun Tay
|
||||||
|
title: Front End Engineer @ Facebook
|
||||||
|
url: https://github.com/yangshun
|
||||||
|
image_url: https://github.com/yangshun.png
|
||||||
|
page: true
|
||||||
|
socials:
|
||||||
|
x: yangshunz
|
||||||
|
github: yangshun
|
||||||
|
|
||||||
|
slorber:
|
||||||
|
name: Sébastien Lorber
|
||||||
|
title: Docusaurus maintainer
|
||||||
|
url: https://sebastienlorber.com
|
||||||
|
image_url: https://github.com/slorber.png
|
||||||
|
page:
|
||||||
|
# customize the url of the author page at /blog/authors/<permalink>
|
||||||
|
permalink: '/all-sebastien-lorber-articles'
|
||||||
|
socials:
|
||||||
|
x: sebastienlorber
|
||||||
|
linkedin: sebastienlorber
|
||||||
|
github: slorber
|
||||||
|
newsletter: https://thisweekinreact.com
|
|
@ -0,0 +1,19 @@
|
||||||
|
facebook:
|
||||||
|
label: Facebook
|
||||||
|
permalink: /facebook
|
||||||
|
description: Facebook tag description
|
||||||
|
|
||||||
|
hello:
|
||||||
|
label: Hello
|
||||||
|
permalink: /hello
|
||||||
|
description: Hello tag description
|
||||||
|
|
||||||
|
docusaurus:
|
||||||
|
label: Docusaurus
|
||||||
|
permalink: /docusaurus
|
||||||
|
description: Docusaurus tag description
|
||||||
|
|
||||||
|
hola:
|
||||||
|
label: Hola
|
||||||
|
permalink: /hola
|
||||||
|
description: Hola tag description
|
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Plugin config types'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /api/plugin-config-types
|
||||||
|
---
|
||||||
|
|
||||||
|
# Plugin config types
|
||||||
|
|
||||||
|
When you're writing a plugin, which registers a content type, you might want to consider that content type as a config type as defined in the Config Sync specification.
|
||||||
|
|
||||||
|
## Register a config type programatically
|
||||||
|
|
||||||
|
You can register a config type by adding some code to the register function of your plugin.
|
||||||
|
|
||||||
|
```md title="register.js"
|
||||||
|
// Register the config type when using the config-sync plugin.
|
||||||
|
if (strapi.plugin('config-sync')) {
|
||||||
|
if (!strapi.plugin('config-sync').pluginTypes) {
|
||||||
|
strapi.plugin('config-sync').pluginTypes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
strapi.plugin('config-sync').pluginTypes.push({
|
||||||
|
configName: 'url-pattern',
|
||||||
|
queryString: 'plugin::webtools.url-pattern',
|
||||||
|
uid: 'code',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to read more about what the different values of a config type actually mean please read the in depth [custom types](/config-types#custom-types) docs
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Custom types'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /configuration/custom-types
|
||||||
|
---
|
||||||
|
|
||||||
|
# Custom types
|
||||||
|
|
||||||
|
With this setting you can register your own custom config types. This is an array which expects objects with at least the `configName`, `queryString` and `uid` properties. Read more about registering custom types in the [Custom config types](/config-types#custom-types) documentation.
|
||||||
|
|
||||||
|
| Name | Details |
|
||||||
|
| ---- | ------- |
|
||||||
|
| Key | `customTypes` |
|
||||||
|
| Required | false |
|
||||||
|
| Type | array |
|
||||||
|
| Default | `[]` |
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Excluded config'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /configuration/excluded-config
|
||||||
|
---
|
||||||
|
|
||||||
|
# Excluded config
|
||||||
|
|
||||||
|
Specify the names of configs you want to exclude from the syncing process. By default the API tokens for users-permissions, which are stored in core_store, are excluded. This setting expects the config names to comply with the naming convention.
|
||||||
|
|
||||||
|
| Name | Details |
|
||||||
|
| ---- | ------- |
|
||||||
|
| Key | `excludedConfig` |
|
||||||
|
| Required | false |
|
||||||
|
| Type | array |
|
||||||
|
| Default | `['core-store.plugin_users-permissions_grant', 'core-store.plugin_upload_metrics', 'core-store.strapi_content_types_schema', 'core-store.ee_information',]` |
|
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Excluded types'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /configuration/excluded-types
|
||||||
|
---
|
||||||
|
|
||||||
|
# Excluded types
|
||||||
|
|
||||||
|
This setting will exclude all the config from a given type from the syncing process. The config types are specified by the `configName` of the type.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
excludedTypes: ['admin-role']
|
||||||
|
```
|
||||||
|
|
||||||
|
| Name | Details |
|
||||||
|
| ---- | ------- |
|
||||||
|
| Key | `excludedTypes` |
|
||||||
|
| Required | false |
|
||||||
|
| Type | array |
|
||||||
|
| Default | `[]` |
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Import on bootstrap'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /configuration/import-on-bootstrap
|
||||||
|
---
|
||||||
|
|
||||||
|
# Import on bootstrap
|
||||||
|
|
||||||
|
Allows you to let the config be imported automaticly when strapi is bootstrapping (on `strapi start`).
|
||||||
|
|
||||||
|
:::danger
|
||||||
|
This setting can't be used locally and should be handled very carefully as it can unintendedly overwrite the changes in your database. **PLEASE USE WITH CARE**.
|
||||||
|
:::
|
||||||
|
|
||||||
|
| Name | Details |
|
||||||
|
| ---- | ------- |
|
||||||
|
| Key | `importOnBootstrap` |
|
||||||
|
| Required | false |
|
||||||
|
| Type | bool |
|
||||||
|
| Default | `false` |
|
|
@ -0,0 +1,32 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Introduction'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /configuration
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🔧 Configuration
|
||||||
|
The settings of the plugin can be overridden in the `config/plugins.js` file.
|
||||||
|
In the example below you can see how, and also what the default settings are.
|
||||||
|
|
||||||
|
```md title="config/plugins.js"
|
||||||
|
module.exports = ({ env }) => ({
|
||||||
|
// ...
|
||||||
|
'config-sync': {
|
||||||
|
enabled: true,
|
||||||
|
config: {
|
||||||
|
syncDir: "config/sync/",
|
||||||
|
minify: false,
|
||||||
|
soft: false,
|
||||||
|
importOnBootstrap: false,
|
||||||
|
customTypes: [],
|
||||||
|
excludedTypes: [],
|
||||||
|
excludedConfig: [
|
||||||
|
"core-store.plugin_users-permissions_grant",
|
||||||
|
"core-store.plugin_upload_metrics",
|
||||||
|
"core-store.strapi_content_types_schema",
|
||||||
|
"core-store.ee_information",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Minify'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /configuration/minify
|
||||||
|
---
|
||||||
|
|
||||||
|
# Minify
|
||||||
|
|
||||||
|
When enabled all the exported JSON files will be minified.
|
||||||
|
|
||||||
|
| Name | Details |
|
||||||
|
| ---- | ------- |
|
||||||
|
| Key | `minify` |
|
||||||
|
| Required | false |
|
||||||
|
| Type | bool |
|
||||||
|
| Default | `false` |
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Soft'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /configuration/soft
|
||||||
|
---
|
||||||
|
|
||||||
|
# Soft
|
||||||
|
|
||||||
|
When enabled the import action will be limited to only create new entries. Entries to be deleted, or updated will be skipped from the import process and will remain in it's original state.
|
||||||
|
|
||||||
|
| Name | Details |
|
||||||
|
| ---- | ------- |
|
||||||
|
| Key | `soft` |
|
||||||
|
| Required | false |
|
||||||
|
| Type | bool |
|
||||||
|
| Default | `false` |
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Sync dir'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /configuration/sync-dir
|
||||||
|
---
|
||||||
|
|
||||||
|
# Sync dir
|
||||||
|
|
||||||
|
The path for reading and writing the sync files.
|
||||||
|
|
||||||
|
| Name | Details |
|
||||||
|
| ---- | ------- |
|
||||||
|
| Key | `syncDir` |
|
||||||
|
| Required | true |
|
||||||
|
| Type | string |
|
||||||
|
| Default | `config/sync/` |
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Admin GUI'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /admin-gui
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🖥️ Admin panel (GUI)
|
||||||
|
This plugin ships with a React app which can be accessed from the settings page in Strapi admin panel. On this page you can pretty much do the same as you can from the CLI. You can import, export and see the difference between the config as found in the sync directory, and the config as found in the database.
|
||||||
|
|
||||||
|
**Pro tip:**
|
||||||
|
By clicking on one of the items in the diff table you can see the exact difference between sync dir and database in a git-style diff viewer.
|
||||||
|
|
||||||
|

|
|
@ -0,0 +1,138 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'CLI'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /cli
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🔌 Command line interface (CLI)
|
||||||
|
|
||||||
|
Add the `config-sync` command as a script to the `package.json` of your Strapi project:
|
||||||
|
|
||||||
|
```
|
||||||
|
"scripts": {
|
||||||
|
// ...
|
||||||
|
"cs": "config-sync"
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now run all the `config-sync` commands like this:
|
||||||
|
|
||||||
|
<Tabs groupId="yarn-npm">
|
||||||
|
<TabItem value="yarn" label="Yarn">
|
||||||
|
```
|
||||||
|
yarn cs --help
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="npm" label="NPM">
|
||||||
|
```
|
||||||
|
npm run cs -- --help
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
## ⬆️ Import ⬇️ Export
|
||||||
|
|
||||||
|
> _Command:_ `import` _Alias:_ `i`
|
||||||
|
>
|
||||||
|
> _Command:_ `export` _Alias:_ `e`
|
||||||
|
|
||||||
|
These commands are used to sync the config in your Strapi project.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
|
||||||
|
<Tabs groupId="yarn-npm">
|
||||||
|
<TabItem value="yarn" label="Yarn">
|
||||||
|
```
|
||||||
|
yarn cs import
|
||||||
|
yarn cs export
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="npm" label="NPM">
|
||||||
|
```
|
||||||
|
npm run cs import
|
||||||
|
npm run cs export
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
:::info
|
||||||
|
When you're using `npm` to run these commands, please note that you need an extra `--` to forward the flags to the script.
|
||||||
|
More information about this topic can be found on the <a href="https://docs.npmjs.com/cli/commands/npm-run-script">NPM documentation</a>.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
npm run cs import -- --yes
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Flag: `-y`, `--yes`
|
||||||
|
|
||||||
|
Use this flag to skip the confirm prompt and go straight to syncing the config.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
[command] --yes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Flag: `-t`, `--type`
|
||||||
|
|
||||||
|
Use this flag to specify the type of config you want to sync.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
[command] --type user-role
|
||||||
|
```
|
||||||
|
|
||||||
|
### Flag: `-p`, `--partial`
|
||||||
|
|
||||||
|
Use this flag to sync a specific set of configs by giving the CLI a comma-separated string of config names.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
[command] --partial user-role.public,i18n-locale.en
|
||||||
|
```
|
||||||
|
|
||||||
|
### Flag: `-f`, `--force`
|
||||||
|
|
||||||
|
If you're using the soft setting to gracefully import config, you can use this flag to ignore the setting for the current command and forcefully import all changes anyway.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
[command] --force
|
||||||
|
```
|
||||||
|
|
||||||
|
## ↔️ Diff
|
||||||
|
|
||||||
|
> _Command:_ `diff` | _Alias:_ `d`
|
||||||
|
|
||||||
|
This command is used to see the difference between the config as found in the sync directory, and the config as found in the database.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
|
||||||
|
<Tabs groupId="yarn-npm">
|
||||||
|
<TabItem value="yarn" label="Yarn">
|
||||||
|
```
|
||||||
|
yarn cs diff
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="npm" label="NPM">
|
||||||
|
```
|
||||||
|
npm run cs diff
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
### Argument: `<single>`
|
||||||
|
|
||||||
|
Add a single config name as the argument of the `diff` command to see the difference of that single file in a git-style diff viewer.
|
||||||
|
|
||||||
|
_Example:_
|
||||||
|
|
||||||
|
<Tabs groupId="yarn-npm">
|
||||||
|
<TabItem value="yarn" label="Yarn">
|
||||||
|
```
|
||||||
|
yarn cs diff user-role.public
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="npm" label="NPM">
|
||||||
|
```
|
||||||
|
npm run cs diff user-role.public
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
|
@ -0,0 +1,125 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Config Types'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /config-types
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🚀 Config types
|
||||||
|
|
||||||
|
By default the plugin will track 4 (official) types.
|
||||||
|
|
||||||
|
To track your own custom types you can register them by setting some plugin config.
|
||||||
|
|
||||||
|
## Default types
|
||||||
|
|
||||||
|
These 4 types are by default registered in the sync process.
|
||||||
|
|
||||||
|
### Admin role
|
||||||
|
|
||||||
|
> Config name: `admin-role` | UID: `code` | Query string: `admin::role`
|
||||||
|
|
||||||
|
### User role
|
||||||
|
|
||||||
|
> Config name: `user-role` | UID: `type` | Query string: `plugin::users-permissions.role`
|
||||||
|
|
||||||
|
### Core store
|
||||||
|
|
||||||
|
> Config name: `core-store` | UID: `key` | Query string: `strapi::core-store`
|
||||||
|
|
||||||
|
### I18n locale
|
||||||
|
|
||||||
|
> Config name: `i18n-locale` | UID: `code` | Query string: `plugin::i18n.locale`
|
||||||
|
|
||||||
|
## Custom types
|
||||||
|
|
||||||
|
Your custom types can be registered through the `customTypes` plugin config. This is a setting that can be set in the `config/plugins.js` file in your project.
|
||||||
|
|
||||||
|
_Read more about the `config/plugins.js` file [here](/configuration)._
|
||||||
|
|
||||||
|
You can register a type by giving the `customTypes` array an object which contains at least the following 3 properties:
|
||||||
|
|
||||||
|
```
|
||||||
|
customTypes: [{
|
||||||
|
configName: 'webhook',
|
||||||
|
queryString: 'webhook',
|
||||||
|
uid: 'name',
|
||||||
|
}],
|
||||||
|
```
|
||||||
|
|
||||||
|
_The example above will register the Strapi webhook type._
|
||||||
|
|
||||||
|
### Config name
|
||||||
|
|
||||||
|
The name of the config type. This value will be used as the first part of the filename for all config of this type. It should be unique from the other types and is preferably written in kebab-case.
|
||||||
|
|
||||||
|
##### Key: `configName`
|
||||||
|
|
||||||
|
> `required:` YES | `type:` string
|
||||||
|
|
||||||
|
### Query string
|
||||||
|
|
||||||
|
This is the query string of the type. Each type in Strapi has its own query string you can use to programatically preform CRUD actions on the entries of the type. Often for custom types in Strapi the format is something like `api::custom-api.custom-type`.
|
||||||
|
|
||||||
|
##### Key: `queryString`
|
||||||
|
|
||||||
|
> `required:` YES | `type:` string
|
||||||
|
|
||||||
|
### UID
|
||||||
|
|
||||||
|
The UID represents a field on the registered type. The value of this field will act as a unique identifier to identify the entries across environments. Therefore it should be unique and preferably un-editable after initial creation.
|
||||||
|
|
||||||
|
Mind that you can not use an auto-incremental value like the `id` as auto-increment does not play nice when you try to match entries across different databases.
|
||||||
|
|
||||||
|
If you do not have a single unique value, you can also pass in an array of keys for a combined uid key. This is for example the case for all content types which use i18n features (An example config would be `uid: ['productId', 'locale']`).
|
||||||
|
|
||||||
|
##### Key: `uid`
|
||||||
|
|
||||||
|
> `required:` YES | `type:` string | string[]
|
||||||
|
|
||||||
|
### Relations
|
||||||
|
|
||||||
|
The relations array specifies the relations you want to include in the sync process.
|
||||||
|
This feature is used to sync the relations between `roles` and `permissions`. See https://github.com/boazpoolman/strapi-plugin-config-sync/blob/master/server/config/types.js#L16.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
configName: 'admin-role',
|
||||||
|
queryString: 'admin::role',
|
||||||
|
uid: 'code',
|
||||||
|
relations: [{
|
||||||
|
queryString: 'admin::permission',
|
||||||
|
relationName: 'permissions',
|
||||||
|
parentName: 'role',
|
||||||
|
relationSortFields: ['action', 'subject'],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Key: `relations`
|
||||||
|
|
||||||
|
> `required:` NO | `type:` array
|
||||||
|
|
||||||
|
### Components
|
||||||
|
|
||||||
|
This property can accept an array of component names from the type. Strapi Components can be included in the export/import process. With "." nested components can also be included in the process.
|
||||||
|
```
|
||||||
|
customTypes: [{
|
||||||
|
configName: 'webhook',
|
||||||
|
queryString: 'webhook',
|
||||||
|
uid: 'name',
|
||||||
|
components: ['ParentComponentA', 'ParentComponentA.ChildComponent', 'ParentComponentB']
|
||||||
|
}],
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Key: `components`
|
||||||
|
|
||||||
|
> `required:` NO | `type:` array
|
||||||
|
|
||||||
|
### JSON fields
|
||||||
|
|
||||||
|
This property can accept an array of field names from the type. It is meant to specify the JSON fields on the type so the plugin can better format the field values when calculating the config difference.
|
||||||
|
|
||||||
|
##### Key: `jsonFields`
|
||||||
|
|
||||||
|
> `required:` NO | `type:` array
|
|
@ -0,0 +1,68 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Installation'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /
|
||||||
|
---
|
||||||
|
|
||||||
|
# ⏳ Installation
|
||||||
|
|
||||||
|
:::prerequisites
|
||||||
|
Complete installation requirements are the exact same as for Strapi itself and can be found in the Strapi documentation.
|
||||||
|
|
||||||
|
**Supported Strapi versions:**
|
||||||
|
|
||||||
|
Strapi v5 use `strapi-plugin-config-sync@^3`
|
||||||
|
|
||||||
|
Strapi v4 use `strapi-plugin-config-sync@^1`
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
Install the plugin in your Strapi project.
|
||||||
|
|
||||||
|
<Tabs groupId="yarn-npm">
|
||||||
|
<TabItem value="yarn" label="Yarn">
|
||||||
|
```
|
||||||
|
yarn add strapi-plugin-config-sync
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="npm" label="NPM">
|
||||||
|
```
|
||||||
|
npm install strapi-plugin-config-sync --save
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
Add the export path to the `watchIgnoreFiles` list in the `config/admin.js` file.
|
||||||
|
This way your app won't reload when you export the config in development.
|
||||||
|
|
||||||
|
```md title="config/admin.js"
|
||||||
|
module.exports = ({ env }) => ({
|
||||||
|
// ...
|
||||||
|
watchIgnoreFiles: [
|
||||||
|
'**/config/sync/**',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
After successful installation you have to rebuild the admin UI so it'll include this plugin. To rebuild and restart Strapi run:
|
||||||
|
|
||||||
|
<Tabs groupId="yarn-npm">
|
||||||
|
<TabItem value="yarn" label="Yarn">
|
||||||
|
```
|
||||||
|
yarn build
|
||||||
|
yarn develop
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="npm" label="NPM">
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
npm run develop
|
||||||
|
```
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
The **Config Sync** plugin should now appear in the **Settings** section of your Strapi app.
|
||||||
|
|
||||||
|
To start tracking your config changes you have to make the first export. This will dump all your configuration data to the `/config/sync` directory. You can export either through [the CLI](/cli) or [Strapi admin panel](/admin-gui)
|
||||||
|
|
||||||
|
Enjoy 🎉
|
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Motivation'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /motivation
|
||||||
|
---
|
||||||
|
|
||||||
|
# 💡 Motivation
|
||||||
|
|
||||||
|
In Strapi we come across what I would call config types. These are models of which the records are stored in our database, just like content types. Though the big difference here is that your code often relies on the database records of these types.
|
||||||
|
|
||||||
|
Having said that, it makes sense that these records can be exported, added to git, and be migrated across environments. This way we can make sure we have all the data our code relies on, on each environment.
|
||||||
|
|
||||||
|
Examples of these types are:
|
||||||
|
|
||||||
|
- Admin roles _(admin::role)_
|
||||||
|
- User roles _(plugin::users-permissions.role)_
|
||||||
|
- Admin settings _(strapi::core-store)_
|
||||||
|
- I18n locale _(plugin::i18n.locale)_
|
||||||
|
|
||||||
|
This plugin gives you the tools to sync this data. You can export the data as JSON files on one env, and import them on every other env. By writing this data as JSON files you can easily track them in your version control system (git).
|
||||||
|
|
||||||
|
_With great power comes great responsibility - Uncle Ben_
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Naming convention'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /naming-convention
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🔍 Naming convention
|
||||||
|
All the config files written in the sync directory have the same naming convention. It goes as follows:
|
||||||
|
|
||||||
|
[config-type].[identifier].json
|
||||||
|
|
||||||
|
- `config-type` - Corresponds to the `configName` of the config type.
|
||||||
|
- `identifier` - Corresponds to the value of the `uid` field of the config type.
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Workflow'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /workflow
|
||||||
|
---
|
||||||
|
|
||||||
|
# ⌨️ Usage / Workflow
|
||||||
|
This plugin works best when you use `git` for the version control of your Strapi project.
|
||||||
|
|
||||||
|
_The following workflows are assuming you're using `git`._
|
||||||
|
|
||||||
|
### Intro
|
||||||
|
All database records tracked with this plugin will be exported to JSON files. Once exported each change to the file or the record will be tracked. Meaning you can now do one of two things:
|
||||||
|
|
||||||
|
- Change the file(s), and run an import. You have now imported from filesystem -> database.
|
||||||
|
- Change the record(s), and run an export. You have now exported from database -> filesystem.
|
||||||
|
|
||||||
|
### Local development
|
||||||
|
When building a new feature locally for your Strapi project you'd use the following workflow:
|
||||||
|
|
||||||
|
- Build the feature.
|
||||||
|
- Export the config.
|
||||||
|
- Commit and push the files to git.
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
When deploying the newly created feature - to either a server, or a co-worker's machine - you'd use the following workflow:
|
||||||
|
|
||||||
|
- Pull the latest file changes to the environment.
|
||||||
|
- (Re)start your Strapi instance.
|
||||||
|
- Import the config.
|
||||||
|
|
||||||
|
## Production deployment
|
||||||
|
The production deployment will be the same as a regular deployment. You just have to be careful before running the import. Ideally making sure the are no open changes before you pull the new code to the environment.
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
sidebar_label: 'Generic update'
|
||||||
|
displayed_sidebar: configSyncSidebar
|
||||||
|
slug: /upgrading/generic-update
|
||||||
|
---
|
||||||
|
|
||||||
|
# Updating Config Sync
|
||||||
|
|
||||||
|
We are always working to make Config Sync better by fixing bugs and introducing new features. These changes will be released as minor or patch versions as defined in the Semantic Versioning specification.
|
||||||
|
|
||||||
|
## Bump a minor/patch version
|
||||||
|
|
||||||
|
When you're updating Config Sync you'll have to follow these steps:
|
||||||
|
|
||||||
|
1. Make sure there are no config changes before starting. Either export or import all staged changes.
|
||||||
|
2. Update the version of the `strapi-plugin-config-sync` package in your `package.json` using your package manager of choice (yarn/npm/pnpm)
|
||||||
|
3. After you've bumped the version make sure to export any new changes that are now shown. It is possible that new configs are introduced, or old ones are updated/removed.
|
||||||
|
4. You're now ready to push these changes an commit them to your source control!
|
|
@ -0,0 +1,147 @@
|
||||||
|
import {themes as prismThemes} from 'prism-react-renderer';
|
||||||
|
import type {Config} from '@docusaurus/types';
|
||||||
|
import type * as Preset from '@docusaurus/preset-classic';
|
||||||
|
|
||||||
|
const config: Config = {
|
||||||
|
title: 'Strapi Config Sync',
|
||||||
|
tagline: "Documentation for the config-sync plugin for Strapi",
|
||||||
|
favicon: 'img/favicon.jpg',
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
'docusaurus-plugin-sass',
|
||||||
|
],
|
||||||
|
|
||||||
|
// Set the production url of your site here
|
||||||
|
url: 'https://docs.pluginpal.io',
|
||||||
|
// Set the /<baseUrl>/ pathname under which your site is served
|
||||||
|
// For GitHub pages deployment, it is often '/<projectName>/'
|
||||||
|
baseUrl: '/config-sync/',
|
||||||
|
|
||||||
|
// GitHub pages deployment config.
|
||||||
|
// If you aren't using GitHub pages, you don't need these.
|
||||||
|
organizationName: 'pluginpal', // Usually your GitHub org/user name.
|
||||||
|
|
||||||
|
onBrokenLinks: 'throw',
|
||||||
|
onBrokenMarkdownLinks: 'warn',
|
||||||
|
|
||||||
|
// Even if you don't use internationalization, you can use this field to set
|
||||||
|
// useful metadata like html lang. For example, if your site is Chinese, you
|
||||||
|
// may want to replace "en" with "zh-Hans".
|
||||||
|
i18n: {
|
||||||
|
defaultLocale: 'en',
|
||||||
|
locales: ['en'],
|
||||||
|
},
|
||||||
|
|
||||||
|
// themes: ['@docusaurus/theme-live-codeblock', '@docusaurus/theme-mermaid'],
|
||||||
|
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
'classic',
|
||||||
|
{
|
||||||
|
docs: {
|
||||||
|
routeBasePath: '/',
|
||||||
|
sidebarPath: './sidebars.ts',
|
||||||
|
// Please change this to your repo.
|
||||||
|
// Remove this to remove the "edit this page" links.
|
||||||
|
editUrl:
|
||||||
|
'https://github.com/pluginpal/strapi-plugin-config-sync/tree/master/docs',
|
||||||
|
admonitions: {
|
||||||
|
keywords: [
|
||||||
|
// Admonitions defaults
|
||||||
|
'note',
|
||||||
|
'tip',
|
||||||
|
'info',
|
||||||
|
'caution',
|
||||||
|
'danger',
|
||||||
|
|
||||||
|
// Admonitions custom
|
||||||
|
'callout',
|
||||||
|
'prerequisites',
|
||||||
|
'strapi',
|
||||||
|
'warning',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
blog: false,
|
||||||
|
sitemap: {
|
||||||
|
lastmod: 'date',
|
||||||
|
changefreq: 'weekly',
|
||||||
|
priority: 0.6,
|
||||||
|
// ignorePatterns: ['/tags/**'],
|
||||||
|
filename: 'sitemap.xml',
|
||||||
|
createSitemapItems: async (params) => {
|
||||||
|
const {defaultCreateSitemapItems, ...rest} = params;
|
||||||
|
const items = await defaultCreateSitemapItems(rest);
|
||||||
|
return items;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
customCss: './src/scss/__index.scss',
|
||||||
|
},
|
||||||
|
} satisfies Preset.Options,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
themeConfig: {
|
||||||
|
// Replace with your project's social card
|
||||||
|
// image: 'img/docusaurus-social-card.jpg',
|
||||||
|
navbar: {
|
||||||
|
title: 'Strapi Config Sync',
|
||||||
|
logo: {
|
||||||
|
alt: 'Config Sync logo',
|
||||||
|
src: 'img/logo.png',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
href: 'https://github.com/pluginpal/strapi-plugin-config-sync',
|
||||||
|
label: 'GitHub',
|
||||||
|
position: 'right',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
style: 'dark',
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
title: 'Community',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: 'Discord',
|
||||||
|
href: 'https://discord.com/invite/strapi',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Forum',
|
||||||
|
href: 'https://forum.strapi.io/',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'More',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: 'Website',
|
||||||
|
href: 'https://www.pluginpal.io',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'GitHub',
|
||||||
|
href: 'https://github.com/pluginpal',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
algolia: {
|
||||||
|
appId: 'ADLP623G89',
|
||||||
|
apiKey: '8f91ceaf54e8e8db14479fd79a420a8c',
|
||||||
|
indexName: 'pluginpal',
|
||||||
|
},
|
||||||
|
|
||||||
|
prism: {
|
||||||
|
theme: prismThemes.github,
|
||||||
|
darkTheme: prismThemes.dracula,
|
||||||
|
},
|
||||||
|
} satisfies Preset.ThemeConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"name": "pluginpal-docs",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"docusaurus": "docusaurus",
|
||||||
|
"start": "docusaurus start",
|
||||||
|
"build": "docusaurus build",
|
||||||
|
"swizzle": "docusaurus swizzle",
|
||||||
|
"deploy": "docusaurus deploy",
|
||||||
|
"clear": "docusaurus clear",
|
||||||
|
"serve": "docusaurus serve",
|
||||||
|
"write-translations": "docusaurus write-translations",
|
||||||
|
"write-heading-ids": "docusaurus write-heading-ids",
|
||||||
|
"typecheck": "tsc"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@docusaurus/core": "3.5.2",
|
||||||
|
"@docusaurus/plugin-sitemap": "^3.5.2",
|
||||||
|
"@docusaurus/preset-classic": "3.5.2",
|
||||||
|
"@docusaurus/theme-live-codeblock": "^3.5.2",
|
||||||
|
"@docusaurus/theme-mermaid": "^3.5.2",
|
||||||
|
"@docusaurus/theme-search-algolia": "^3.5.2",
|
||||||
|
"@mdx-js/react": "^3.0.0",
|
||||||
|
"classnames": "^2.5.1",
|
||||||
|
"clsx": "^2.0.0",
|
||||||
|
"docusaurus-plugin-sass": "^0.2.5",
|
||||||
|
"prism-react-renderer": "^2.3.0",
|
||||||
|
"react": "^18.0.0",
|
||||||
|
"react-dom": "^18.0.0",
|
||||||
|
"sass": "^1.78.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@docusaurus/module-type-aliases": "3.5.2",
|
||||||
|
"@docusaurus/tsconfig": "3.5.2",
|
||||||
|
"@docusaurus/types": "3.5.2",
|
||||||
|
"typescript": "~5.5.2"
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.5%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 3 chrome version",
|
||||||
|
"last 3 firefox version",
|
||||||
|
"last 5 safari version"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
- create an ordered group of docs
|
||||||
|
- render a sidebar for each doc of that group
|
||||||
|
- provide next/previous navigation
|
||||||
|
|
||||||
|
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||||
|
|
||||||
|
Create as many sidebars as you want.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||||
|
const sidebars = {
|
||||||
|
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||||
|
// tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||||
|
|
||||||
|
// But you can create a sidebar manually
|
||||||
|
configSyncSidebar: [
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
collapsed: false,
|
||||||
|
label: "🚀 Getting Started",
|
||||||
|
items: [
|
||||||
|
"getting-started/installation",
|
||||||
|
"getting-started/motivation",
|
||||||
|
"getting-started/cli",
|
||||||
|
"getting-started/admin-gui",
|
||||||
|
"getting-started/config-types",
|
||||||
|
"getting-started/workflow",
|
||||||
|
"getting-started/naming-convention",
|
||||||
|
// "dev-docs/usage-information",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
collapsed: false,
|
||||||
|
label: "⚙️ Configuration",
|
||||||
|
items: [
|
||||||
|
"configuration/introduction",
|
||||||
|
"configuration/sync-dir",
|
||||||
|
"configuration/minify",
|
||||||
|
"configuration/import-on-bootstrap",
|
||||||
|
"configuration/custom-types",
|
||||||
|
"configuration/soft",
|
||||||
|
"configuration/excluded-types",
|
||||||
|
"configuration/excluded-config",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
collapsed: false,
|
||||||
|
label: "📦 API",
|
||||||
|
items: [
|
||||||
|
"api/plugin-config-types",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
collapsed: false,
|
||||||
|
label: "♻️ Upgrading",
|
||||||
|
items: [
|
||||||
|
"upgrading/generic-update",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = sidebars;
|
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react'
|
||||||
|
import clsx from 'clsx'
|
||||||
|
|
||||||
|
export default function ApiCall({
|
||||||
|
children,
|
||||||
|
noSideBySide = false,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
'api-call',
|
||||||
|
(noSideBySide && 'api-call--no-side-by-side'),
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
import React from 'react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
|
||||||
|
export default function Badge({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
link = '',
|
||||||
|
noLink = false,
|
||||||
|
variant = '',
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const variantNormalized = variant.toLowerCase().replace(/\W/g, '');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className={clsx(
|
||||||
|
'badge',
|
||||||
|
'badge--feature',
|
||||||
|
(variantNormalized && `badge--${variantNormalized.toLowerCase()}`),
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{(noLink || !link) ? (
|
||||||
|
<>
|
||||||
|
{variant}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<a className="badge__link" href={link}>
|
||||||
|
{variant}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
{children}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AlphaBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="Alpha"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function BetaBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="Beta"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FutureBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="Future"
|
||||||
|
link="/dev-docs/configurations/features"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EnterpriseBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="Enterprise"
|
||||||
|
link="https://strapi.io/pricing-self-hosted"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CloudProBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="Strapi Cloud Pro"
|
||||||
|
link="https://strapi.io/pricing-cloud"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CloudTeamBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="Strapi Cloud Team"
|
||||||
|
link="https://strapi.io/pricing-cloud"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export function CloudDevBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="Strapi Cloud Dev"
|
||||||
|
link="https://strapi.io/pricing-cloud"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function NewBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="New ✨"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function UpdatedBadge(props) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
variant="Updated ️🖌"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import React from 'react';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
import styles from './button.module.scss';
|
||||||
|
|
||||||
|
export function Button({
|
||||||
|
href,
|
||||||
|
to,
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
decorative,
|
||||||
|
size = '',
|
||||||
|
variant = 'primary',
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const ButtonElement = (to ? Link : (href ? 'a' : 'button'));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ButtonElement
|
||||||
|
{...rest}
|
||||||
|
{...(!href ? {} : { href, target: '_blank' })}
|
||||||
|
{...(!to ? {} : { to })}
|
||||||
|
className={clsx(
|
||||||
|
'button',
|
||||||
|
(variant && styles[`button--${variant}`]),
|
||||||
|
(size && styles[`button--${size}`]),
|
||||||
|
styles.button,
|
||||||
|
styles[variant],
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
{decorative && (
|
||||||
|
<span className={styles.button__decorative}>
|
||||||
|
{decorative}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</ButtonElement>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/** Component: Button */
|
||||||
|
|
||||||
|
@import '../../scss/_mixins.scss';
|
||||||
|
|
||||||
|
.button {
|
||||||
|
--strapi-button-background-color: var(--strapi-primary-600);
|
||||||
|
--strapi-button-border-color: var(--strapi-primary-600);
|
||||||
|
--strapi-button-border-radius: 4px;
|
||||||
|
--strapi-button-box-shadow: 0 0 0 transparent;
|
||||||
|
--strapi-button-color: #fff;
|
||||||
|
--strapi-button-font-size: 12px;
|
||||||
|
--strapi-button-font-weight: 600;
|
||||||
|
--strapi-button-line-height: 16px;
|
||||||
|
--strapi-button-position: relative;
|
||||||
|
--strapi-button-py: 7px;
|
||||||
|
--strapi-button-px: 15px;
|
||||||
|
--strapi-button-transition-property: color, background, border-color, box-shadow;
|
||||||
|
|
||||||
|
--strapi-button-hover-background-color: var(--strapi-primary-700);
|
||||||
|
--strapi-button-hover-border-color: var(--strapi-primary-700);
|
||||||
|
--strapi-button-hover-box-shadow: 0px 9px 10px rgba(44, 56, 148, 0.2475);
|
||||||
|
--strapi-button-hover-color: #fff;
|
||||||
|
|
||||||
|
--ifm-button-color: var(--strapi-button-color);
|
||||||
|
--ifm-button-background-color: var(--strapi-button-background-color);
|
||||||
|
--ifm-button-border-color: var(--strapi-button-border-color);
|
||||||
|
--ifm-button-border-radius: var(--strapi-button-border-radius);
|
||||||
|
--ifm-button-font-weight: var(--strapi-button-font-weight);
|
||||||
|
--ifm-button-padding-horizontal: var(--strapi-button-px);
|
||||||
|
--ifm-button-padding-vertical: var(--strapi-button-py);
|
||||||
|
--ifm-button-size-multiplier: 1;
|
||||||
|
|
||||||
|
--ifm-color-primary-darker: var(--strapi-primary-200);
|
||||||
|
|
||||||
|
--ifm-link-hover-color: var(--strapi-button-color);
|
||||||
|
--ifm-link-hover-decoration: none;
|
||||||
|
|
||||||
|
position: var(--strapi-button-position);
|
||||||
|
font-size: var(--strapi-button-font-size);
|
||||||
|
line-height: var(--strapi-button-line-height);
|
||||||
|
box-shadow: var(--strapi-button-box-shadow);
|
||||||
|
transition-property: var(--strapi-button-transition-property);
|
||||||
|
|
||||||
|
&__decorative {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
bottom: -16px;
|
||||||
|
right: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled),
|
||||||
|
&:not([aria-disabled="true"]) {
|
||||||
|
&:focus, &:hover {
|
||||||
|
--strapi-button-box-shadow: var(--strapi-button-hover-box-shadow);
|
||||||
|
--strapi-button-background-color: var(--strapi-button-hover-background-color);
|
||||||
|
--strapi-button-border-color: var(--strapi-button-hover-border-color);
|
||||||
|
--strapi-button-color: var(--strapi-button-hover-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sizes */
|
||||||
|
&--huge {
|
||||||
|
--strapi-button-border-radius: 6px;
|
||||||
|
--strapi-button-font-size: 15px;
|
||||||
|
--strapi-button-line-height: 23px;
|
||||||
|
--strapi-button-py: 11px;
|
||||||
|
--strapi-button-px: 71px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Variants */
|
||||||
|
&--secondary {
|
||||||
|
--strapi-button-background-color: #f0f0ff;
|
||||||
|
--strapi-button-border-color: #d9d8ff;
|
||||||
|
--strapi-button-color: var(--strapi-primary-600);
|
||||||
|
|
||||||
|
--strapi-button-hover-background-color: var(--strapi-neutral-0);
|
||||||
|
--strapi-button-hover-border-color: #d9d8ff;
|
||||||
|
--strapi-button-hover-box-shadow: none;
|
||||||
|
--strapi-button-hover-color: var(--strapi-primary-600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
.button {
|
||||||
|
/** Dark mode Variants */
|
||||||
|
&--secondary {
|
||||||
|
--strapi-button-background-color: var(--strapi-neutral-100);
|
||||||
|
--strapi-button-border-color: var(--strapi-neutral-200);
|
||||||
|
|
||||||
|
--strapi-button-hover-background-color: var(--strapi-neutral-0);
|
||||||
|
--strapi-button-hover-border-color: var(--strapi-neutral-200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
import React from 'react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
import styles from './card.module.scss';
|
||||||
|
import IconArrow from '@site/static/img/assets/icons/arrow-right.svg';
|
||||||
|
|
||||||
|
export function CardTitle({
|
||||||
|
as,
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
withArrow,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const TitleElement = (as || 'h3');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TitleElement
|
||||||
|
className={clsx(
|
||||||
|
styles.card__title,
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
{withArrow && (
|
||||||
|
<span className={styles.card__title__arrow}>
|
||||||
|
<IconArrow />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</TitleElement>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CardDescription({
|
||||||
|
as,
|
||||||
|
className,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const DescriptionElement = (as || 'div');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DescriptionElement
|
||||||
|
className={clsx(
|
||||||
|
styles.card__description,
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CardImgBg({
|
||||||
|
className,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
className={clsx(
|
||||||
|
styles['card__img-bg'],
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CardImg({
|
||||||
|
className,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
className={clsx(
|
||||||
|
styles['card__img'],
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Card({
|
||||||
|
className,
|
||||||
|
href,
|
||||||
|
isContentDelimited,
|
||||||
|
to,
|
||||||
|
variant,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const asCallToAction = !!(href || to);
|
||||||
|
const CardElement = (to ? Link : (href ? 'a' : 'div'));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CardElement
|
||||||
|
{...(!href ? {} : { href, target: '_blank' })}
|
||||||
|
{...(!to ? {} : { to })}
|
||||||
|
className={clsx(
|
||||||
|
styles.card,
|
||||||
|
(asCallToAction && styles['card--cta']),
|
||||||
|
(isContentDelimited && styles['card--content-delimited']),
|
||||||
|
(variant && styles[`card--${variant}`]),
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
/** Component: Card */
|
||||||
|
|
||||||
|
@import '../../scss/_mixins.scss';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--strapi-card-background: var(--strapi-neutral-0);
|
||||||
|
--strapi-card-border-color: #EDEDFF;
|
||||||
|
--strapi-card-border-radius: 10px;
|
||||||
|
--strapi-card-box-shadow: 0 0 0 transparent;
|
||||||
|
--strapi-card-content-delimited: 395px;
|
||||||
|
--strapi-card-img-border-width: 5px;
|
||||||
|
--strapi-card-img-border-radius: 5px 5px 0 0;
|
||||||
|
--strapi-card-img-bg-scale: 1;
|
||||||
|
--strapi-card-justify-content: center;
|
||||||
|
--strapi-card-position: relative;
|
||||||
|
--strapi-card-overflow: hidden;
|
||||||
|
--strapi-card-text-align: center;
|
||||||
|
--strapi-card-gap: var(--strapi-spacing-2);
|
||||||
|
--strapi-card-px: var(--strapi-spacing-6);
|
||||||
|
--strapi-card-py: var(--strapi-spacing-6);
|
||||||
|
--strapi-card-title-arrow-left: var(--strapi-card-gap);
|
||||||
|
--strapi-card-title-color: #1D1B84;
|
||||||
|
--strapi-card-title-font-size: 17px;
|
||||||
|
--strapi-card-title-font-weight: 700;
|
||||||
|
--strapi-card-title-line-height: 26px;
|
||||||
|
--strapi-card-description-color: #4E6294;
|
||||||
|
--strapi-card-description-font-size: 15px;
|
||||||
|
--strapi-card-description-line-height: 24px;
|
||||||
|
--strapi-card-hover-border-color: #D6D6FF;
|
||||||
|
--strapi-card-hover-img-bg-scale: 1.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
position: var(--strapi-card-position);
|
||||||
|
overflow: var(--strapi-card-overflow);
|
||||||
|
background: var(--strapi-card-background);
|
||||||
|
border-radius: var(--strapi-card-border-radius);
|
||||||
|
border: 1px solid var(--strapi-card-border-color);
|
||||||
|
box-shadow: var(--strapi-card-box-shadow);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--strapi-card-gap);
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: var(--strapi-card-justify-content);
|
||||||
|
text-align: var(--strapi-card-text-align);
|
||||||
|
padding: var(--strapi-card-py) var(--strapi-card-px);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&:focus, &:hover {
|
||||||
|
--strapi-card-border-color: var(--strapi-card-hover-border-color);
|
||||||
|
--strapi-card-title-arrow-left: var(--strapi-spacing-3);
|
||||||
|
--strapi-card-img-bg-scale: var(--strapi-card-hover-img-bg-scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
display: block;
|
||||||
|
color: var(--strapi-card-title-color);
|
||||||
|
font-size: var(--strapi-card-title-font-size);
|
||||||
|
font-weight: var(--strapi-card-title-font-weight);
|
||||||
|
line-height: var(--strapi-card-title-line-height);
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__arrow {
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 0;
|
||||||
|
margin-left: var(--strapi-card-title-arrow-left);
|
||||||
|
transition: margin-left 0.1s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
--ifm-link-color: var(--strapi-card-description-color);
|
||||||
|
--ifm-link-decoration: underline;
|
||||||
|
|
||||||
|
color: var(--strapi-card-description-color);
|
||||||
|
opacity: 0.8;
|
||||||
|
font-size: var(--strapi-card-description-font-size);
|
||||||
|
line-height: var(--strapi-card-description-line-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__img {
|
||||||
|
border-bottom: none;
|
||||||
|
box-shadow: 0 1px 10px 0 #7A78B61A;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--cta {
|
||||||
|
--ifm-link-color: currentColor;
|
||||||
|
--strapi-card-background:
|
||||||
|
linear-gradient(
|
||||||
|
310deg,
|
||||||
|
rgba(168, 166, 255, 0.15) 1.16%,
|
||||||
|
rgba(226, 225, 255, 0.15) 69.23%
|
||||||
|
),
|
||||||
|
#FFFFFF
|
||||||
|
;
|
||||||
|
--strapi-card-text-align: left;
|
||||||
|
--strapi-card-gap: var(--strapi-spacing-2);
|
||||||
|
--strapi-card-title-font-size: 21px;
|
||||||
|
--strapi-card-title-font-weight: 600;
|
||||||
|
--strapi-card-title-line-height: 28px;
|
||||||
|
--ifm-link-decoration: none;
|
||||||
|
--ifm-link-hover-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--content-delimited {
|
||||||
|
.card {
|
||||||
|
&__title,
|
||||||
|
&__description {
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--strapi-card-content-delimited);
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
:root {
|
||||||
|
--strapi-card-px: var(--strapi-spacing-8);
|
||||||
|
--strapi-card-py: var(--strapi-spacing-9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
&__title {
|
||||||
|
&__arrow {
|
||||||
|
transition: margin-left 0.2s ease;
|
||||||
|
will-change: margin-left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus, &:hover {
|
||||||
|
&.card--cta {
|
||||||
|
--strapi-card-border-color: #D6D6FF;
|
||||||
|
--strapi-card-box-shadow: 0px 1px 4px rgba(33, 33, 52, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--cta {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
will-change: border-color, box-shadow, color;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
&__img {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
will-change: border-radius, transform;
|
||||||
|
transform:
|
||||||
|
scale(var(--strapi-card-img-scale, 1))
|
||||||
|
translate(var(--strapi-card-img-translate, '0, 0'))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
--strapi-card-border-color: var(--strapi-neutral-150);
|
||||||
|
--strapi-card-title-color: var(--strapi-netral-1000);
|
||||||
|
--strapi-card-description-color: var(--strapi-netral-1000);
|
||||||
|
--strapi-card-img-border-color: rgba(255, 255, 255, 0.5);
|
||||||
|
--strapi-card-hover-border-color: #49494D;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
&--cta {
|
||||||
|
--strapi-card-background: var(--strapi-neutral-0);
|
||||||
|
|
||||||
|
&:focus, &:hover {
|
||||||
|
--strapi-card-border-color: #49494D;
|
||||||
|
--strapi-card-color: var(--strapi-neutral-1000);
|
||||||
|
|
||||||
|
--ifm-link-hover-color: var(--strapi-neutral-1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import React from 'react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import styles from './container.module.scss';
|
||||||
|
|
||||||
|
export function Container({ className, ...rest }) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
styles.container,
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/** Component: Container */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--strapi-container-px: var(--ifm-spacing-horizontal);
|
||||||
|
--strapi-container-mw: calc(863px + calc(var(--strapi-container-px) * 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
padding-right: var(--strapi-container-px);
|
||||||
|
padding-left: var(--strapi-container-px);
|
||||||
|
max-width: var(--strapi-container-mw);
|
||||||
|
width: 100%;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
import React from 'react'
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
export default function CustomDocCard(props) {
|
||||||
|
const { title, description, link, emoji, small = false } = props;
|
||||||
|
const linkClasses = classNames({
|
||||||
|
card: true,
|
||||||
|
cardContainer: true,
|
||||||
|
'padding--lg': !small,
|
||||||
|
'padding--md': small,
|
||||||
|
});
|
||||||
|
const cardClasses = classNames({
|
||||||
|
'custom-doc-card': true,
|
||||||
|
'margin-bottom--lg': !small,
|
||||||
|
'margin-bottom--sm': small,
|
||||||
|
'custom-doc-card--small': small,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<article className={ cardClasses }>
|
||||||
|
<a className={ linkClasses }
|
||||||
|
href={ link }
|
||||||
|
>
|
||||||
|
<h2 className="text--truncate cardTitle" title={title}>
|
||||||
|
{emoji ? emoji : '📄️'} {title}
|
||||||
|
</h2>
|
||||||
|
<p className="text--truncate cardDescription" title={ description }>
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function CustomDocCardsWrapper({ children }) {
|
||||||
|
return (
|
||||||
|
<div className="custom-cards-wrapper">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './features-list.module.scss';
|
||||||
|
import { LinkWithArrow } from '../LinkWithArrow/LinkWithArrow';
|
||||||
|
|
||||||
|
export function FeatureListItem({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
href,
|
||||||
|
icon: Icon,
|
||||||
|
iconColor,
|
||||||
|
label,
|
||||||
|
to,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const ContentElement = ((href || to) ? LinkWithArrow : 'span');
|
||||||
|
const IconElement = ((href || to) ? 'a' : 'span');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
className={clsx(
|
||||||
|
styles['features-list__item'],
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{Icon && (
|
||||||
|
<IconElement
|
||||||
|
className={clsx(
|
||||||
|
styles['features-list__item__icon'],
|
||||||
|
(iconColor && styles[`features-list__item__icon--${iconColor}`]),
|
||||||
|
)}
|
||||||
|
href={href}
|
||||||
|
to={to}
|
||||||
|
{...(IconElement === 'a' ? { href: to || href } : {})}
|
||||||
|
>
|
||||||
|
<Icon />
|
||||||
|
</IconElement>
|
||||||
|
)}
|
||||||
|
<ContentElement
|
||||||
|
className={styles['features-list__item__content']}
|
||||||
|
href={href}
|
||||||
|
to={to}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{children || label}
|
||||||
|
</ContentElement>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FeaturesList({
|
||||||
|
className,
|
||||||
|
id,
|
||||||
|
icon,
|
||||||
|
iconColor,
|
||||||
|
items,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const defaultId = `featureListItem${Math.random()}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul
|
||||||
|
className={clsx(
|
||||||
|
styles['features-list'],
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{items?.map((featureListItem, featureListItemIndex) => {
|
||||||
|
return (
|
||||||
|
<FeatureListItem
|
||||||
|
key={`${id || defaultId}${featureListItemIndex}`}
|
||||||
|
icon={icon}
|
||||||
|
iconColor={iconColor}
|
||||||
|
{...featureListItem}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/** Component: Features List */
|
||||||
|
|
||||||
|
@import '../../scss/_mixins.scss';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--strapi-features-list-gap: var(--strapi-spacing-2);
|
||||||
|
--strapi-features-list-margin: 0;
|
||||||
|
--strapi-features-list-py: var(--ifm-spacing-horizontal);
|
||||||
|
--strapi-features-list-px: 0;
|
||||||
|
|
||||||
|
--strapi-features-list-item-inner-gap: 8px;
|
||||||
|
--strapi-features-list-item-icon-background-color: var(--strapi-secondary-100);
|
||||||
|
--strapi-features-list-item-icon-border-color: #D4EDFF;
|
||||||
|
--strapi-features-list-item-icon-color: var(--strapi-secondary-500);
|
||||||
|
--strapi-features-list-item-icon-border-radius: 7px;
|
||||||
|
--strapi-features-list-item-icon-area: 32px;
|
||||||
|
--strapi-features-list-item-icon-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.features-list {
|
||||||
|
margin: var(--strapi-features-list-margin);
|
||||||
|
padding: var(--strapi-features-list-py) var(--strapi-features-list-px);
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: var(--strapi-features-list-gap);
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--strapi-features-list-item-inner-gap);
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
background-color: var(--strapi-features-list-item-icon-background-color);
|
||||||
|
border: 1px solid var(--strapi-features-list-item-icon-border-color);
|
||||||
|
border-radius: var(--strapi-features-list-item-icon-border-radius);
|
||||||
|
color: var(--strapi-features-list-item-icon-color);
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: var(--strapi-features-list-item-icon-area);
|
||||||
|
width: var(--strapi-features-list-item-icon-area);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&--green {
|
||||||
|
--strapi-features-list-item-icon-background-color: var(--strapi-success-100);
|
||||||
|
--strapi-features-list-item-icon-border-color: #DAF0D8;
|
||||||
|
--strapi-features-list-item-icon-color: var(--strapi-success-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: var(--strapi-features-list-item-icon-size);
|
||||||
|
width: var(--strapi-features-list-item-icon-size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
:root {
|
||||||
|
--strapi-features-list-py: calc(var(--ifm-spacing-horizontal) * 2);
|
||||||
|
--strapi-features-list-px: var(--ifm-spacing-horizontal);
|
||||||
|
|
||||||
|
--strapi-features-list-item-inner-gap: 20px;
|
||||||
|
--strapi-features-list-item-icon-area: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
--strapi-features-list-item-icon-background-color: var(--strapi-secondary-500);
|
||||||
|
--strapi-features-list-item-icon-border-color: var(--strapi-secondary-600);
|
||||||
|
|
||||||
|
.features-list {
|
||||||
|
&__item {
|
||||||
|
&__icon {
|
||||||
|
--strapi-features-list-item-icon-color: #fff;
|
||||||
|
|
||||||
|
&--green {
|
||||||
|
--strapi-features-list-item-icon-background-color: var(--strapi-success-500);
|
||||||
|
--strapi-features-list-item-icon-border-color: var(--strapi-success-600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import React from 'react';
|
||||||
|
import styles from './hero.module.scss';
|
||||||
|
|
||||||
|
export function HeroTitle({
|
||||||
|
className,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<h1
|
||||||
|
className={clsx(
|
||||||
|
styles.hero__title,
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function HeroDescription({
|
||||||
|
className,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
styles.hero__description,
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Hero({
|
||||||
|
className,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<header
|
||||||
|
className={clsx(
|
||||||
|
styles.hero,
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/** Component: Hero */
|
||||||
|
|
||||||
|
@import '../../scss/_mixins.scss';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--strapi-hero-py: var(--strapi-spacing-6);
|
||||||
|
--strapi-hero-gap: var(--strapi-spacing-4);
|
||||||
|
|
||||||
|
--strapi-hero-title-color: #1D1B84;
|
||||||
|
--strapi-hero-title-font-size: var(--strapi-font-size-xl);
|
||||||
|
--strapi-hero-title-line-height: 1.25;
|
||||||
|
|
||||||
|
--strapi-hero-description-color: #4E6294;
|
||||||
|
--strapi-hero-description-font-size: var(--strapi-font-size-lg);
|
||||||
|
--strapi-hero-description-line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
padding-top: var(--strapi-hero-py);
|
||||||
|
padding-bottom: var(--strapi-hero-py);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
color: var(--strapi-hero-title-color);
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: var(--strapi-hero-title-font-size);
|
||||||
|
line-height: var(--strapi-hero-title-line-height);
|
||||||
|
letter-spacing: 0.4px;
|
||||||
|
margin: 0 0 var(--strapi-hero-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
color: var(--strapi-hero-description-color);
|
||||||
|
font-size: var(--strapi-hero-description-font-size);
|
||||||
|
line-height: var(--strapi-hero-description-line-height);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
:root {
|
||||||
|
--strapi-hero-py: 40px;
|
||||||
|
--strapi-hero-title-font-size: 43px;
|
||||||
|
--strapi-hero-title-line-height: 56px;
|
||||||
|
--strapi-hero-description-font-size: 21px;
|
||||||
|
--strapi-hero-description-line-height: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
--strapi-hero-title-color: white;
|
||||||
|
--strapi-hero-description-color: white;
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
|
type FeatureItem = {
|
||||||
|
title: string;
|
||||||
|
Svg: React.ComponentType<React.ComponentProps<'svg'>>;
|
||||||
|
description: JSX.Element;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FeatureList: FeatureItem[] = [
|
||||||
|
{
|
||||||
|
title: 'Easy to Use',
|
||||||
|
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
|
||||||
|
description: (
|
||||||
|
<>
|
||||||
|
Docusaurus was designed from the ground up to be easily installed and
|
||||||
|
used to get your website up and running quickly.
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Focus on What Matters',
|
||||||
|
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
|
||||||
|
description: (
|
||||||
|
<>
|
||||||
|
Docusaurus lets you focus on your docs, and we'll do the chores. Go
|
||||||
|
ahead and move your docs into the <code>docs</code> directory.
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Powered by React',
|
||||||
|
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
|
||||||
|
description: (
|
||||||
|
<>
|
||||||
|
Extend or customize your website layout by reusing React. Docusaurus can
|
||||||
|
be extended while reusing the same header and footer.
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function Feature({title, Svg, description}: FeatureItem) {
|
||||||
|
return (
|
||||||
|
<div className={clsx('col col--4')}>
|
||||||
|
<div className="text--center">
|
||||||
|
<Svg className={styles.featureSvg} role="img" />
|
||||||
|
</div>
|
||||||
|
<div className="text--center padding-horiz--md">
|
||||||
|
<Heading as="h3">{title}</Heading>
|
||||||
|
<p>{description}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function HomepageFeatures(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<section className={styles.features}>
|
||||||
|
<div className="container">
|
||||||
|
<div className="row">
|
||||||
|
{FeatureList.map((props, idx) => (
|
||||||
|
<Feature key={idx} {...props} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
.features {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 2rem 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureSvg {
|
||||||
|
height: 200px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import React from 'react';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
import IconArrow from '@site/static/img/assets/icons/arrow-right.svg';
|
||||||
|
import styles from './link-with-arrow.module.scss';
|
||||||
|
|
||||||
|
export function LinkWithArrow({
|
||||||
|
apart = false,
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
href,
|
||||||
|
to,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const LinkElement = (to ? Link : 'a');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LinkElement
|
||||||
|
className={clsx(
|
||||||
|
styles.lwa,
|
||||||
|
(apart && styles['lwa--apart']),
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...(href && { href, target: '_blank' })}
|
||||||
|
{...(to && { to })}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
<span className={styles.lwa__content}>
|
||||||
|
{children}
|
||||||
|
</span>
|
||||||
|
<IconArrow
|
||||||
|
className={styles.lwa__icon}
|
||||||
|
/>
|
||||||
|
</LinkElement>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/** Component: Link with Arrow */
|
||||||
|
|
||||||
|
@import '../../scss/_mixins.scss';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--strapi-lwa-icon-ml: var(--strapi-spacing-2);
|
||||||
|
--strapi-lwa-font-size: 14px;
|
||||||
|
--strapi-lwa-font-weight: 500;
|
||||||
|
--strapi-lwa-line-height: 20px;
|
||||||
|
--strapi-lwa-hover-icon-ml: var(--strapi-spacing-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lwa {
|
||||||
|
--ifm-link-color: #1D1B84;
|
||||||
|
--ifm-link-decoration: none;
|
||||||
|
--ifm-link-hover-color: #2825B8;
|
||||||
|
--ifm-link-hover-decoration: none;
|
||||||
|
|
||||||
|
font-size: var(--strapi-lwa-font-size);
|
||||||
|
font-weight: var(--strapi-lwa-font-weight);
|
||||||
|
line-height: var(--strapi-lwa-line-height);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&:focus, &:hover {
|
||||||
|
--strapi-lwa-icon-ml: var(--strapi-lwa-hover-icon-ml);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 0;
|
||||||
|
margin-left: var(--strapi-lwa-icon-ml);
|
||||||
|
transition: margin-left 0.1s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--apart {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.lwa {
|
||||||
|
&__content {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
.lwa {
|
||||||
|
--ifm-link-color: var(--strapi-neutral-1000);
|
||||||
|
--ifm-link-hover-color: var(--strapi-neutral-500);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default function Request({
|
||||||
|
children,
|
||||||
|
title = 'Example request',
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="api-call__request">
|
||||||
|
<div className="api-call__request__heading">{title}</div>
|
||||||
|
<div className="api-call__request__content">{children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default function Response({
|
||||||
|
children,
|
||||||
|
title = 'Example response',
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="api-call__response">
|
||||||
|
<div className="api-call__response__heading">{title}</div>
|
||||||
|
<div className="api-call__response__content">{children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function SubtleCallout({
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
emoji = '🤓',
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="theme-admonition theme-admonition--callout theme-admonition--subtle">
|
||||||
|
<div className="theme-admonition__heading">
|
||||||
|
<span style={{fontWeight: 300}} className="theme-admonition__heading__icon">{ emoji } </span>{ title }
|
||||||
|
</div>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export * from './Button/Button';
|
||||||
|
export * from './Card/Card';
|
||||||
|
export * from './Container/Container';
|
||||||
|
export * from './HomepageFeatures';
|
||||||
|
export * from './FeaturesList/FeaturesList';
|
||||||
|
export * from './Hero/Hero';
|
||||||
|
export * from './LinkWithArrow/LinkWithArrow';
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* Any CSS included here will be global.
|
||||||
|
* The classic template bundles Infima by default.
|
||||||
|
* Infima is a CSS framework designed to work well for content-centric websites.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Core */
|
||||||
|
@import '_mixins.scss';
|
||||||
|
@import '_tokens.scss';
|
||||||
|
@import '_tokens-overrides.scss';
|
||||||
|
|
||||||
|
/** Base */
|
||||||
|
@import '_fonts.scss';
|
||||||
|
@import '_base.scss';
|
||||||
|
|
||||||
|
/** Components */
|
||||||
|
@import 'admonition.scss';
|
||||||
|
@import 'api-call.scss';
|
||||||
|
@import 'badge.scss';
|
||||||
|
@import 'breadcrumbs.scss';
|
||||||
|
@import 'card.scss';
|
||||||
|
@import 'columns.scss';
|
||||||
|
@import 'container.scss';
|
||||||
|
@import 'custom-doc-cards.scss';
|
||||||
|
@import 'details.scss';
|
||||||
|
@import 'footer.scss';
|
||||||
|
@import 'grid.scss';
|
||||||
|
@import 'images.scss';
|
||||||
|
@import 'markdown.scss';
|
||||||
|
@import 'medium-zoom.scss';
|
||||||
|
@import 'navbar.scss';
|
||||||
|
@import 'pagination-nav.scss';
|
||||||
|
@import 'search.scss';
|
||||||
|
@import 'scene.scss';
|
||||||
|
@import 'sidebar.scss';
|
||||||
|
@import 'table.scss';
|
||||||
|
@import 'tabs.scss';
|
||||||
|
@import 'table-of-contents.scss';
|
||||||
|
@import 'typography.scss';
|
|
@ -0,0 +1,44 @@
|
||||||
|
/** Base: General Styles */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--custom-selection-background-color: var(--strapi-primary-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background-color: var(--custom-selection-background-color);
|
||||||
|
color: var(--custom-selection-color, var(--strapi-neutral-0));
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
article:first-child:not(.col):not(.custom-doc-card),
|
||||||
|
article:first-child:not(.col) + nav {
|
||||||
|
--custom-main-px: var(--strapi-spacing-0);
|
||||||
|
--custom-main-width: 683px;
|
||||||
|
|
||||||
|
max-width: calc(var(--custom-main-width) + calc(var(--strapi-spacing-4) * 2));
|
||||||
|
padding-left: var(--custom-main-px) !important;
|
||||||
|
padding-right: var(--custom-main-px) !important;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
main {
|
||||||
|
article:first-child:not(.col),
|
||||||
|
article:first-child:not(.col) + nav {
|
||||||
|
--custom-main-px: var(--strapi-spacing-4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
.container img[width="16"] {
|
||||||
|
/* 'Temporary' fix while we figure a way to display white icons in dark mode 😅 */
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
/** Fonts */
|
||||||
|
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&display=swap');
|
||||||
|
|
||||||
|
.font-poppins,
|
||||||
|
.font-poppins button,
|
||||||
|
.font-poppins input {
|
||||||
|
--custom-font-family: "Poppins", sans-serif;
|
||||||
|
--ifm-heading-font-family: "Poppins", sans-serif;
|
||||||
|
|
||||||
|
font-family: var(--custom-font-family);
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/** Core: Sass Mixins */
|
||||||
|
|
||||||
|
/** Mixin: Responsive */
|
||||||
|
@mixin small-up {
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mixin: Responsive */
|
||||||
|
@mixin medium-up {
|
||||||
|
@media (min-width: 997px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mixin: Responsive */
|
||||||
|
@mixin large-up {
|
||||||
|
@media (min-width: 1536px) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mixin: Dark mode */
|
||||||
|
@mixin dark {
|
||||||
|
html[data-theme='dark'] {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mixin: Light mode */
|
||||||
|
@mixin light {
|
||||||
|
html[data-theme='light'] {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mixin: Transition */
|
||||||
|
@mixin transition {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mixin: Flex */
|
||||||
|
@mixin flex-row(
|
||||||
|
$gap: var(--strapi-spacing-2),
|
||||||
|
$align-items: center,
|
||||||
|
$justify-content: null
|
||||||
|
) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: $gap;
|
||||||
|
align-items: $align-items;
|
||||||
|
justify-content: $justify-content;
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/** Core: Docusaurus/Infima Style Tokens Overrides */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
--ifm-background-color: var(--strapi-neutral-0);
|
||||||
|
--ifm-color-content: var(--strapi-neutral-800);
|
||||||
|
--ifm-font-color-base: var(--strapi-neutral-800);
|
||||||
|
|
||||||
|
--ifm-color-content-secondary: var(--strapi-neutral-600);
|
||||||
|
--ifm-color-emphasis-100: var(--strapi-neutral-100);
|
||||||
|
--ifm-color-emphasis-200: var(--strapi-neutral-150);
|
||||||
|
--ifm-color-emphasis-300: var(--strapi-neutral-200);
|
||||||
|
--ifm-color-emphasis-400: var(--strapi-neutral-300);
|
||||||
|
--ifm-color-emphasis-500: var(--strapi-neutral-400);
|
||||||
|
--ifm-color-emphasis-600: var(--strapi-neutral-500);
|
||||||
|
--ifm-color-emphasis-700: var(--strapi-neutral-600);
|
||||||
|
--ifm-color-emphasis-800: var(--strapi-neutral-700);
|
||||||
|
--ifm-color-emphasis-900: var(--strapi-neutral-800);
|
||||||
|
--ifm-color-emphasis-1000: var(--strapi-neutral-1000);
|
||||||
|
|
||||||
|
--ifm-color-primary: var(--strapi-primary-600);
|
||||||
|
--ifm-color-primary-dark: var(--strapi-primary-700);
|
||||||
|
--ifm-color-primary-darker: var(--strapi-primary-800);
|
||||||
|
--ifm-color-primary-darkest: var(--strapi-primary-900);
|
||||||
|
--ifm-color-primary-light: var(--strapi-primary-500);
|
||||||
|
--ifm-color-primary-lighter: var(--strapi-primary-400);
|
||||||
|
--ifm-color-primary-lightest: var(--strapi-primary-300);
|
||||||
|
|
||||||
|
--ifm-link-color: var(--strapi-primary-600);
|
||||||
|
--ifm-link-decoration: none;
|
||||||
|
// --ifm-link-hover-decoration: none;
|
||||||
|
|
||||||
|
--ifm-paragraph-margin-bottom: var(--strapi-spacing-4);
|
||||||
|
|
||||||
|
--ifm-scrollbar-track-background-color: var(--strapi-neutral-100);
|
||||||
|
--ifm-scrollbar-thumb-background-color: var(--strapi-neutral-200);
|
||||||
|
--ifm-scrollbar-thumb-hover-background-color: var(--strapi-neutral-300);
|
||||||
|
|
||||||
|
--ifm-table-stripe-background: #DCDCE43E;
|
||||||
|
--ifm-toc-border-color: var(--strapi-neutral-150);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode */
|
||||||
|
@include dark {
|
||||||
|
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
|
||||||
|
|
||||||
|
--ifm-background-color: var(--strapi-neutral-0);
|
||||||
|
--ifm-color-content: var(--strapi-neutral-800);
|
||||||
|
--ifm-font-color-base: var(--strapi-neutral-800);
|
||||||
|
|
||||||
|
--ifm-color-emphasis-100: var(--strapi-neutral-100);
|
||||||
|
--ifm-color-emphasis-200: var(--strapi-neutral-150);
|
||||||
|
--ifm-color-emphasis-300: var(--strapi-neutral-200);
|
||||||
|
--ifm-color-emphasis-400: var(--strapi-neutral-300);
|
||||||
|
--ifm-color-emphasis-500: var(--strapi-neutral-400);
|
||||||
|
--ifm-color-emphasis-600: var(--strapi-neutral-500);
|
||||||
|
--ifm-color-emphasis-700: var(--strapi-neutral-600);
|
||||||
|
--ifm-color-emphasis-800: var(--strapi-neutral-700);
|
||||||
|
--ifm-color-emphasis-900: var(--strapi-neutral-800);
|
||||||
|
--ifm-color-emphasis-1000: var(--strapi-neutral-1000);
|
||||||
|
|
||||||
|
--ifm-color-primary: var(--strapi-primary-600);
|
||||||
|
--ifm-color-primary-dark: var(--strapi-primary-700);
|
||||||
|
--ifm-color-primary-darker: var(--strapi-primary-800);
|
||||||
|
--ifm-color-primary-darkest: var(--strapi-primary-900);
|
||||||
|
--ifm-color-primary-light: var(--strapi-primary-500);
|
||||||
|
--ifm-color-primary-lighter: var(--strapi-primary-400);
|
||||||
|
--ifm-color-primary-lightest: var(--strapi-primary-300);
|
||||||
|
|
||||||
|
--ifm-link-color: var(--strapi-primary-500);
|
||||||
|
|
||||||
|
--ifm-navbar-background-color: #212134;
|
||||||
|
|
||||||
|
--ifm-scrollbar-track-background-color: var(--strapi-neutral-100);
|
||||||
|
--ifm-scrollbar-thumb-background-color: var(--strapi-neutral-150);
|
||||||
|
--ifm-scrollbar-thumb-hover-background-color: var(--strapi-neutral-200);
|
||||||
|
|
||||||
|
--ifm-toc-border-color: var(--strapi-neutral-150);
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/** Core: Strapi Design System Tokens */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/** Spacing */
|
||||||
|
--strapi-spacing-0: 0; // 0px
|
||||||
|
--strapi-spacing-1: 0.25rem; // 4px
|
||||||
|
--strapi-spacing-2: 0.5rem; // 8px
|
||||||
|
--strapi-spacing-3: 0.75rem; // 12px
|
||||||
|
--strapi-spacing-4: 1rem; // 16px
|
||||||
|
--strapi-spacing-5: 1.25rem; // 20px
|
||||||
|
--strapi-spacing-6: 1.5rem; // 24px
|
||||||
|
--strapi-spacing-7: 2rem; // 32px
|
||||||
|
--strapi-spacing-8: 2.5rem; // 40px
|
||||||
|
--strapi-spacing-9: 3rem; // 48px
|
||||||
|
--strapi-spacing-10: 3.5rem; // 56px
|
||||||
|
--strapi-spacing-11: 3.75rem; // 64px
|
||||||
|
|
||||||
|
/** Fonts */
|
||||||
|
--strapi-font-size-tiny: 0.625rem; // 10px
|
||||||
|
--strapi-font-size-xxs: 0.6875rem; // 11px
|
||||||
|
--strapi-font-size-xs: 0.75rem; // 12px
|
||||||
|
--strapi-font-size-ssm: 0.8125rem; // 13px
|
||||||
|
--strapi-font-size-sm: 0.875rem; // 14px
|
||||||
|
--strapi-font-size-md: 1rem; // 16px
|
||||||
|
--strapi-font-size-lg: 1.125rem; // 18px
|
||||||
|
--strapi-font-size-xl: 2rem; // 32px
|
||||||
|
|
||||||
|
/** Color: Neutral */
|
||||||
|
--strapi-neutral-1000: #181826;
|
||||||
|
--strapi-neutral-900: #212134;
|
||||||
|
--strapi-neutral-800: #32324D;
|
||||||
|
--strapi-neutral-700: #4A4A6A;
|
||||||
|
--strapi-neutral-600: #666687;
|
||||||
|
--strapi-neutral-500: #8E8EA9;
|
||||||
|
--strapi-neutral-400: #A5A5BA;
|
||||||
|
--strapi-neutral-300: #C0C0CF;
|
||||||
|
--strapi-neutral-200: #DCDCE4;
|
||||||
|
--strapi-neutral-150: #EAEAEF;
|
||||||
|
--strapi-neutral-100: #F6F6F9;
|
||||||
|
--strapi-neutral-0: #FFFFFF;
|
||||||
|
|
||||||
|
/** Color: Primary */
|
||||||
|
--strapi-primary-700: #271FE0;
|
||||||
|
--strapi-primary-600: #4945FF;
|
||||||
|
--strapi-primary-500: #7B79FF;
|
||||||
|
--strapi-primary-200: #D9D8FF;
|
||||||
|
--strapi-primary-100: #F0F0FF;
|
||||||
|
|
||||||
|
/** Color: Secondary */
|
||||||
|
--strapi-secondary-700: #006096;
|
||||||
|
--strapi-secondary-600: #0C75AF;
|
||||||
|
--strapi-secondary-500: #66B7F1;
|
||||||
|
--strapi-secondary-200: #B8E1FF;
|
||||||
|
--strapi-secondary-100: #EAF5FF;
|
||||||
|
|
||||||
|
/** Color: Success */
|
||||||
|
--strapi-success-700: #2F6846;
|
||||||
|
--strapi-success-600: #328048;
|
||||||
|
--strapi-success-500: #5CB176;
|
||||||
|
--strapi-success-300: #BBEFB5; /* not in Figma, used for code blocks */
|
||||||
|
--strapi-success-200: #C6F0C2;
|
||||||
|
--strapi-success-100: #EAFBE7;
|
||||||
|
|
||||||
|
/** Color: Danger */
|
||||||
|
--strapi-danger-800: #4B1113; /* not actually existing in Figma */
|
||||||
|
--strapi-danger-700: #B72B1A;
|
||||||
|
--strapi-danger-600: #D02B20;
|
||||||
|
--strapi-danger-500: #EE5E52;
|
||||||
|
--strapi-danger-200: #F5C0B8;
|
||||||
|
--strapi-danger-100: #FCECEA;
|
||||||
|
|
||||||
|
/** Color: Warning */
|
||||||
|
--strapi-warning-700: #BE5D01;
|
||||||
|
--strapi-warning-600: #D9822F;
|
||||||
|
--strapi-warning-500: #F29D41;
|
||||||
|
--strapi-warning-200: #FAE7B9;
|
||||||
|
--strapi-warning-100: #FDF4DC;
|
||||||
|
|
||||||
|
/** Color: Alternative */
|
||||||
|
--strapi-alternative-600: #9736E8;
|
||||||
|
--strapi-alternative-500: #AC73E6;
|
||||||
|
--strapi-alternative-200: #E0C1F4;
|
||||||
|
--strapi-alternative-100: #F6ECFC;
|
||||||
|
|
||||||
|
/** Color: Code */
|
||||||
|
--strapi-code-fluo-green: #50FA7B;
|
||||||
|
--strapi-code-green: #50FA7B;
|
||||||
|
--strapi-code-rose: #FF79C6;
|
||||||
|
--strapi-code-purple: #BD93F9;
|
||||||
|
--strapi-code-dark-blue: #6272A4;
|
||||||
|
|
||||||
|
/** Components */
|
||||||
|
--strapi-input-border-color: var(--strapi-neutral-200);
|
||||||
|
--strapi-input-border-width: 1px;
|
||||||
|
--strapi-input-border-style: solid;
|
||||||
|
--strapi-input-border:
|
||||||
|
var(--strapi-input-border-width)
|
||||||
|
var(--strapi-input-border-style)
|
||||||
|
var(--strapi-input-border-color)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
/** Dark Color: Neutral */
|
||||||
|
--strapi-neutral-1000: #FFFFFF; /* both 800 and 900 identical in Figma */
|
||||||
|
--strapi-neutral-900: #FFFFFF; /* both 800 and 900 identical in Figma */
|
||||||
|
--strapi-neutral-800: #FFFFFF;
|
||||||
|
--strapi-neutral-700: #EAEAEF;
|
||||||
|
--strapi-neutral-600: #666687;
|
||||||
|
--strapi-neutral-500: #c0c0cf;
|
||||||
|
--strapi-neutral-400: #A5A5BA; /* incorrecly named in Figma */
|
||||||
|
--strapi-neutral-300: #666687;
|
||||||
|
--strapi-neutral-200: #4A4A6A;
|
||||||
|
--strapi-neutral-150: #32324D;
|
||||||
|
--strapi-neutral-100: #181826;
|
||||||
|
--strapi-neutral-0: #212134;
|
||||||
|
|
||||||
|
/** Dark Color: Primary */
|
||||||
|
--strapi-primary-600: #7B79FF;
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
/** Component: Alert */
|
||||||
|
|
||||||
|
.theme-admonition {
|
||||||
|
--custom-admonition-background-color: var(--strapi-neutral-100);
|
||||||
|
--custom-admonition-border-color: var(--strapi-neutral-500);
|
||||||
|
--custom-admonition-border-radius: var(--strapi-spacing-0);
|
||||||
|
--custom-admonition-color: var(--strapi-neutral-800);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-neutral-700);
|
||||||
|
--custom-admonition-heading-mb: var(--strapi-spacing-2);
|
||||||
|
--custom-admonition-mb: var(--strapi-spacing-4);
|
||||||
|
--custom-admonition-px: var(--strapi-spacing-4);
|
||||||
|
--custom-admonition-py: var(--strapi-spacing-4);
|
||||||
|
|
||||||
|
--ifm-link-decoration: none;
|
||||||
|
--ifm-link-color: var(--custom-admonition-heading-color);
|
||||||
|
--ifm-link-hover-color: var(--custom-admonition-heading-color);
|
||||||
|
|
||||||
|
background-color: var(--custom-admonition-background-color);
|
||||||
|
border-left: 4px solid var(--custom-admonition-border-color);
|
||||||
|
border-radius: var(--custom-admonition-border-radius);
|
||||||
|
color: var(--custom-admonition-color);
|
||||||
|
margin: 0 0 var(--custom-admonition-mb);
|
||||||
|
padding: var(--custom-admonition-py) var(--custom-admonition-px);
|
||||||
|
|
||||||
|
/** Alert Title element */
|
||||||
|
&__heading {
|
||||||
|
color: var(--custom-admonition-heading-color);
|
||||||
|
font-weight: var(--custom-admonition-heading-font-weight, 600);
|
||||||
|
margin-bottom: var(--custom-admonition-heading-mb);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, li, p, table {
|
||||||
|
code,
|
||||||
|
a code {
|
||||||
|
--custom-code-border-color: transparent;
|
||||||
|
--custom-code-background-color: var(--custom-admonition-code-background-color);
|
||||||
|
--custom-code-color: var(--custom-admonition-heading-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
*:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info,
|
||||||
|
&--callout,
|
||||||
|
&--prerequisites {
|
||||||
|
--custom-admonition-background-color: var(--strapi-neutral-100);
|
||||||
|
--custom-admonition-border-color: var(--strapi-neutral-500);
|
||||||
|
--custom-admonition-code-background-color: var(--strapi-neutral-200);
|
||||||
|
--custom-admonition-code-color: var(--strapi-primary-600);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-neutral-700);
|
||||||
|
|
||||||
|
--custom-selection-background-color: var(--strapi-neutral-700);
|
||||||
|
--custom-selection-color: var(--strapi-neutral-100);
|
||||||
|
|
||||||
|
--ifm-link-color: var(--strapi-primary-600);
|
||||||
|
--ifm-link-hover-color: var(--strapi-primary-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--note {
|
||||||
|
--custom-admonition-background-color: var(--strapi-secondary-100);
|
||||||
|
--custom-admonition-border-color: var(--strapi-secondary-500);
|
||||||
|
--custom-admonition-code-background-color: var(--strapi-secondary-200);
|
||||||
|
--custom-admonition-code-color: var(--strapi-secondary-600);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-secondary-700);
|
||||||
|
|
||||||
|
--custom-selection-background-color: var(--strapi-secondary-700);
|
||||||
|
--custom-selection-color: var(--strapi-secondary-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--tip,
|
||||||
|
&--success {
|
||||||
|
--custom-admonition-background-color: var(--strapi-success-100);
|
||||||
|
--custom-admonition-border-color: var(--strapi-success-500);
|
||||||
|
--custom-admonition-code-background-color: var(--strapi-success-200);
|
||||||
|
--custom-admonition-code-color: var(--strapi-success-600);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-success-700);
|
||||||
|
|
||||||
|
--custom-selection-background-color: var(--strapi-success-700);
|
||||||
|
--custom-selection-color: var(--strapi-success-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--caution {
|
||||||
|
--custom-admonition-background-color: var(--strapi-warning-100);
|
||||||
|
--custom-admonition-border-color: var(--strapi-warning-500);
|
||||||
|
--custom-admonition-code-background-color: var(--strapi-warning-200);
|
||||||
|
--custom-admonition-code-color: var(--strapi-warning-600);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-warning-700);
|
||||||
|
|
||||||
|
--custom-selection-background-color: var(--strapi-warning-700);
|
||||||
|
--custom-selection-color: var(--strapi-warning-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--danger,
|
||||||
|
&--warning {
|
||||||
|
--custom-admonition-background-color: var(--strapi-danger-100);
|
||||||
|
--custom-admonition-border-color: var(--strapi-danger-500);
|
||||||
|
--custom-admonition-code-background-color: var(--strapi-danger-200);
|
||||||
|
--custom-admonition-code-color: var(--strapi-danger-600);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-danger-700);
|
||||||
|
|
||||||
|
--custom-selection-background-color: var(--strapi-danger-700);
|
||||||
|
--custom-selection-color: var(--strapi-danger-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--strapi {
|
||||||
|
--custom-admonition-background-color: var(--strapi-primary-100);
|
||||||
|
--custom-admonition-border-color: var(--strapi-primary-500);
|
||||||
|
--custom-admonition-code-background-color: var(--strapi-primary-200);
|
||||||
|
--custom-admonition-code-color: var(--strapi-primary-600);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-primary-700);
|
||||||
|
|
||||||
|
--custom-selection-background-color: var(--strapi-primary-700);
|
||||||
|
--custom-selection-color: var(--strapi-primary-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--subtle {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
border: solid 1px var(--strapi-neutral-500);
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 997px) {
|
||||||
|
[class*="sbs-column"]:nth-of-type(2) .theme-admonition--subtle {
|
||||||
|
margin-left: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
.theme-admonition {
|
||||||
|
// --custom-admonition-color: var(--strapi-neutral-150);
|
||||||
|
--custom-admonition-background-color: var(--strapi-neutral-100);
|
||||||
|
--custom-admonition-code-background-color: var(--strapi-neutral-200);
|
||||||
|
|
||||||
|
&--info,
|
||||||
|
&--callout,
|
||||||
|
&--prerequisites {
|
||||||
|
--custom-admonition-code-color: var(--strapi-primary-500);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-neutral-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--note {
|
||||||
|
--custom-admonition-code-color: var(--strapi-secondary-500);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-secondary-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--tip,
|
||||||
|
&--success {
|
||||||
|
--custom-admonition-code-color: var(--strapi-success-500);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-success-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--caution,
|
||||||
|
&--warning {
|
||||||
|
--custom-admonition-code-color: var(--strapi-warning-500);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-warning-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--danger {
|
||||||
|
--custom-admonition-code-color: var(--strapi-danger-500);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-danger-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--strapi {
|
||||||
|
--custom-admonition-code-color: var(--strapi-primary-500);
|
||||||
|
--custom-admonition-heading-color: var(--strapi-primary-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
code,
|
||||||
|
a code {
|
||||||
|
--custom-code-border-color: transparent;
|
||||||
|
--custom-code-background-color: var(--custom-admonition-code-background-color);
|
||||||
|
--custom-code-color: var(--custom-admonition-code-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.strapi-iqb {
|
||||||
|
--strapi-iqb-background-color: var(--strapi-neutral-0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
/** Component: API Call / Request / Response */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--custom-api-call-gap: var(--strapi-spacing-4);
|
||||||
|
--custom-api-call-heading-font-size: var(--strapi-font-size-sm);
|
||||||
|
--custom-api-call-heading-font-weight: 700;
|
||||||
|
--custom-api-call-heading-py: var(--strapi-spacing-2);
|
||||||
|
--custom-api-call-heading-px: var(--strapi-spacing-4);
|
||||||
|
--custom-api-call-radius: var(--strapi-spacing-2);
|
||||||
|
--custom-api-call-response-heading-background-color: var(--strapi-neutral-200);
|
||||||
|
--custom-api-call-response-content-background-color: var(--strapi-neutral-300);
|
||||||
|
--custom-api-call-request-heading-background-color: var(--strapi-neutral-100);
|
||||||
|
--custom-api-call-request-content-background-color: var(--strapi-neutral-150);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-call {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
gap: var(--custom-api-call-gap);
|
||||||
|
margin-bottom: var(--custom-api-call-gap);
|
||||||
|
|
||||||
|
&__request__content,
|
||||||
|
&__request__heading,
|
||||||
|
&__response__content,
|
||||||
|
&__response__heading {
|
||||||
|
background-color: var(--custom-api-call-background-color);
|
||||||
|
color: var(--custom-api-call-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__request,
|
||||||
|
&__response {
|
||||||
|
border-radius: var(--custom-api-call-radius);
|
||||||
|
|
||||||
|
&__heading,
|
||||||
|
&__content {
|
||||||
|
*:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__heading {
|
||||||
|
border-top-left-radius: var(--custom-api-call-radius);
|
||||||
|
border-top-right-radius: var(--custom-api-call-radius);
|
||||||
|
font-size: var(--custom-api-call-heading-font-size);
|
||||||
|
font-weight: var(--custom-api-call-heading-font-weight);
|
||||||
|
padding: var(--custom-api-call-heading-py) var(--custom-api-call-heading-px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
border-bottom-left-radius: var(--custom-api-call-radius);
|
||||||
|
border-bottom-right-radius: var(--custom-api-call-radius);
|
||||||
|
padding: var(--custom-api-call-content-py) var(--custom-api-call-content-px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__request {
|
||||||
|
&__heading {
|
||||||
|
--custom-api-call-background-color: var(--custom-api-call-request-heading-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
--custom-api-call-background-color: var(--custom-api-call-request-content-background-color);
|
||||||
|
--custom-api-call-content-py: var(--custom-api-call-heading-px);
|
||||||
|
--custom-api-call-content-px: var(--custom-api-call-heading-px);
|
||||||
|
|
||||||
|
--custom-code-block-background-color: var(--custom-api-call-response-heading-background-color);
|
||||||
|
|
||||||
|
--custom-code-background-color: var(--custom-api-call-response-heading-background-color);
|
||||||
|
--custom-code-border-color: transparent;
|
||||||
|
--custom-code-color: currentColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__response {
|
||||||
|
&__heading {
|
||||||
|
--custom-api-call-background-color: var(--custom-api-call-request-content-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
--custom-api-call-background-color: var(--custom-api-call-request-content-background-color);
|
||||||
|
|
||||||
|
--custom-code-block-background-color: var(--custom-api-call-response-content-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-code-block {
|
||||||
|
border-radius: var(--custom-api-call-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
--custom-api-call-color: var(--strapi-neutral-1000);
|
||||||
|
|
||||||
|
--custom-api-call-request-heading-background-color: var(--strapi-neutral-300);
|
||||||
|
--custom-api-call-request-content-background-color: var(--strapi-neutral-200);
|
||||||
|
|
||||||
|
--custom-api-call-response-heading-background-color: var(--strapi-neutral-150);
|
||||||
|
--custom-api-call-response-content-background-color: var(--strapi-neutral-100);
|
||||||
|
|
||||||
|
.api-call {
|
||||||
|
&__request {
|
||||||
|
&__content {
|
||||||
|
pre {
|
||||||
|
--custom-code-block-background-color: var(--custom-api-call-response-heading-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__response {
|
||||||
|
&__content {
|
||||||
|
pre {
|
||||||
|
--custom-code-block-background-color: var(--custom-api-call-response-content-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/** Component: Feature Badges (alpha, beta) */
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
--custom-badge-background-color: var(--strapi-neutral-200);
|
||||||
|
--custom-badge-color: var(--strapi-neutral-800);
|
||||||
|
--custom-badge-font-size: var(--strapi-font-size-sm);
|
||||||
|
|
||||||
|
--custom-selection-background-color: var(--custom-badge-color);
|
||||||
|
|
||||||
|
--ifm-badge-background-color: var(--custom-badge-background-color);
|
||||||
|
--ifm-badge-color: var(--custom-badge-color);
|
||||||
|
--ifm-badge-border-radius: var(--strapi-spacing-1);
|
||||||
|
--ifm-badge-padding-horizontal: var(--strapi-spacing-2);
|
||||||
|
--ifm-badge-padding-vertical: var(--strapi-spacing-2);
|
||||||
|
|
||||||
|
--ifm-font-weight-bold: var(--strapi-font-size-sm);
|
||||||
|
--ifm-link-color: var(--ifm-badge-color);
|
||||||
|
--ifm-link-hover-color: var(--ifm-badge-color);
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
top: var(--custom-badge-inside-titles-top);
|
||||||
|
font-size: var(--custom-badge-font-size);
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&-link {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--alpha {
|
||||||
|
--custom-badge-background-color: rgb(255,230,228);
|
||||||
|
--custom-badge-color: rgb(219, 0, 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--beta {
|
||||||
|
--custom-badge-background-color: rgb(246, 228, 253);
|
||||||
|
--custom-badge-color: rgb(160,25,240);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--future {
|
||||||
|
--custom-badge-background-color: var(--strapi-danger-200);
|
||||||
|
--custom-badge-color: rgb(219, 0, 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--enterprise {
|
||||||
|
--custom-badge-background-color: rgb(255, 241, 209);
|
||||||
|
--custom-badge-color: rgb(229, 136, 41);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--strapicloudpro {
|
||||||
|
--custom-badge-background-color: rgb(55, 34, 254);
|
||||||
|
--custom-badge-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--strapicloudteam {
|
||||||
|
--custom-badge-background-color: rgb(154, 53, 242);
|
||||||
|
--custom-badge-color: #fff;
|
||||||
|
}
|
||||||
|
&--strapiclouddev {
|
||||||
|
--custom-badge-background-color: rgb(44,170,73);
|
||||||
|
--custom-badge-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--new {
|
||||||
|
--custom-badge-background-color: var(--strapi-warning-100);
|
||||||
|
--custom-badge-border-color: var(--strapi-warning-200);
|
||||||
|
--custom-badge-color: var(--strapi-warning-700);
|
||||||
|
|
||||||
|
--ifm-badge-padding-horizontal: 2px;
|
||||||
|
--ifm-badge-padding-vertical: 2px;
|
||||||
|
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
letter-spacing: -0.5px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
min-width: 52px;
|
||||||
|
border: 1px solid var(--custom-badge-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&--updated {
|
||||||
|
--custom-badge-background-color: var(--strapi-secondary-100);
|
||||||
|
--custom-badge-border-color: var(--strapi-secondary-200);
|
||||||
|
--custom-badge-color: var(--strapi-secondary-600);
|
||||||
|
|
||||||
|
--ifm-badge-padding-horizontal: 2px;
|
||||||
|
--ifm-badge-padding-vertical: 2px;
|
||||||
|
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
letter-spacing: -0.5px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
min-width: 52px;
|
||||||
|
border: 1px solid var(--custom-badge-border-color);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 .badge {
|
||||||
|
--custom-badge-inside-titles-top: -.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 .badge {
|
||||||
|
--custom-badge-inside-titles-top: -.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
.badge {
|
||||||
|
&--new {
|
||||||
|
--custom-badge-background-color: var(--strapi-neutral-100);
|
||||||
|
--custom-badge-border-color: var(--strapi-warning-500);
|
||||||
|
--custom-badge-color: var(--strapi-warning-500);
|
||||||
|
}
|
||||||
|
&--updated {
|
||||||
|
--custom-badge-background-color: var(--strapi-neutral-100);
|
||||||
|
--custom-badge-border-color: var(--strapi-secondary-500);
|
||||||
|
--custom-badge-color: var(--strapi-secondary-500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/** Component: Breadcrumbs */
|
||||||
|
|
||||||
|
.breadcrumbs {
|
||||||
|
--ifm-breadcrumb-item-background-active: transparent;
|
||||||
|
--ifm-breadcrumb-border-radius: var(--strapi-spacing-1);
|
||||||
|
--ifm-breadcrumb-color-active: var(--strapi-neutral-800);
|
||||||
|
--ifm-link-hover-color: var(--strapi-neutral-700);
|
||||||
|
|
||||||
|
--custom-breadcrumbs-font-size: var(--strapi-font-size-xs);
|
||||||
|
--custom-breadcrumbs-pt: var(--strapi-spacing-4);
|
||||||
|
--custom-breadcrumbs-item-caret-mx: var(--strapi-spacing-1);
|
||||||
|
|
||||||
|
padding: var(--custom-breadcrumbs-pt) 0 0;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
&:after {
|
||||||
|
--ifm-breadcrumb-spacing: var(--custom-breadcrumbs-item-caret-mx);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
background-color: transparent;
|
||||||
|
font-size: var(--custom-breadcrumbs-font-size);
|
||||||
|
|
||||||
|
@include transition;
|
||||||
|
|
||||||
|
&:any-link:hover {
|
||||||
|
--ifm-breadcrumb-item-background-active: var(--strapi-neutral-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include medium-up {
|
||||||
|
.breadcrumbs {
|
||||||
|
--custom-breadcrumbs-pt: var(--strapi-spacing-6);
|
||||||
|
--custom-breadcrumbs-item-caret-mx: var(--strapi-spacing-3);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/** Component: Card */
|
||||||
|
|
||||||
|
:root body {
|
||||||
|
--custom-card-border-color: var(--strapi-neutral-200);
|
||||||
|
|
||||||
|
--ifm-card-background-color: var(--strapi-neutral-0);
|
||||||
|
--ifm-card-border-radius: var(--strapi-spacing-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
--ifm-color-emphasis-200: var(--custom-card-border-color);
|
||||||
|
|
||||||
|
border: 1px solid var(--custom-card-border-color);
|
||||||
|
box-shadow: 0px 1px 4px rgba(33, 33, 52, 0.1) !important;
|
||||||
|
@include transition;
|
||||||
|
|
||||||
|
&[href] {
|
||||||
|
color: var(--strapi-neutral-600);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
--ifm-color-primary: var(--strapi-neutral-300);
|
||||||
|
|
||||||
|
box-shadow: 0px 2px 15px rgba(33, 33, 52, 0.1) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
--ifm-h2-font-size: var(--strapi-font-size-md);
|
||||||
|
margin-bottom: var(--strapi-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: var(--strapi-font-size-sm);
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
.card {
|
||||||
|
&[href] {
|
||||||
|
color: var(--strapi-neutral-700);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/** Components: Columns */
|
||||||
|
|
||||||
|
.column {
|
||||||
|
&__title {
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: var(--strapi-spacing-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
.columns {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: var(--strapi-spacing-4);
|
||||||
|
|
||||||
|
> .column {
|
||||||
|
flex: 1;
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
/** Component: Container */
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/** Component: CustomDocCardWrapper */
|
||||||
|
|
||||||
|
.custom-cards-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
max-width: 715px;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.custom-doc-card {
|
||||||
|
max-width: 320px;
|
||||||
|
width: 320px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-right: 20px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
height: 170px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Component: CustomDocCard */
|
||||||
|
.custom-doc-card {
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
.cardTitle {
|
||||||
|
color: var(--strapi-primary-600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text--truncate.cardDescription {
|
||||||
|
// cancel --truncate styles since we can't remove the' class
|
||||||
|
overflow: auto;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-doc-card--small {
|
||||||
|
.cardTitle {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/** Component: Details/Accordion */
|
||||||
|
|
||||||
|
details.alert {
|
||||||
|
--docusaurus-details-decoration-color: var(--strapi-neutral-800);
|
||||||
|
|
||||||
|
--ifm-alert-background-color: var(--strapi-neutral-150);
|
||||||
|
--ifm-alert-background-color-highlight: var(--strapi-neutral-500);
|
||||||
|
--ifm-alert-border-radius: var(--strapi-spacing-1);
|
||||||
|
--ifm-alert-foreground-color: var( --ifm-color-info-contrast-foreground );
|
||||||
|
--ifm-alert-border-color: transparent;
|
||||||
|
|
||||||
|
--ifm-tabs-color-active: var(--ifm-color-primary);
|
||||||
|
--ifm-tabs-color-active-border: var(--ifm-color-primary);
|
||||||
|
|
||||||
|
summary {
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Content element */
|
||||||
|
> div > div {
|
||||||
|
--docusaurus-details-decoration-color: transparent;
|
||||||
|
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--custom-code-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: var(--ifm-link-decoration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark {
|
||||||
|
details a {
|
||||||
|
color: var(--strapi-primary-500);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/** Component: Footer */
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
a {
|
||||||
|
@include transition;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.footer--dark {
|
||||||
|
--ifm-footer-background-color: var(--strapi-neutral-700);
|
||||||
|
--ifm-footer-link-hover-color: var(--strapi-neutral-0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
.footer {
|
||||||
|
&.footer--dark {
|
||||||
|
--ifm-footer-background-color: var(--strapi-neutral-150);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/** Component: Grid */
|
||||||
|
|
||||||
|
.row {
|
||||||
|
--custom-grid-spacing: var(--strapi-spacing-2);
|
||||||
|
--ifm-spacing-horizontal: var(--custom-grid-spacing);
|
||||||
|
|
||||||
|
.col {
|
||||||
|
&.margin-bottom--lg {
|
||||||
|
margin-bottom: calc(var(--custom-grid-spacing) * 2) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
.row {
|
||||||
|
&--huge {
|
||||||
|
--custom-grid-spacing: var(--strapi-spacing-4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
/** General: Images */
|
||||||
|
|
||||||
|
/** Dark Mode images border */
|
||||||
|
.theme-doc-markdown.markdown [class*="themedImage--dark"] {
|
||||||
|
border: 0.125rem solid var(--strapi-neutral-200);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/** Component: Markdown */
|
||||||
|
|
||||||
|
$selector-markdown: ".theme-doc-markdown.markdown";
|
||||||
|
|
||||||
|
#{$selector-markdown} {
|
||||||
|
--custom-markdown-pt: var(--strapi-spacing-0);
|
||||||
|
--custom-markdown-pb: var(--strapi-spacing-2);
|
||||||
|
|
||||||
|
--markdown-link-color: var(--strapi-primary-600);
|
||||||
|
|
||||||
|
font-weight: 400;
|
||||||
|
padding: var(--custom-markdown-pt) 0 var(--custom-markdown-pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
#{$selector-markdown} {
|
||||||
|
--markdown-link-color: var(--strapi-primary-600);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/** Component: Medium Zoom */
|
||||||
|
|
||||||
|
.medium-zoom {
|
||||||
|
&-overlay {
|
||||||
|
background: var(--strapi-neutral-150) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
.medium-zoom {
|
||||||
|
&-image {
|
||||||
|
&--opened {
|
||||||
|
margin-top: var(--ifm-navbar-height) !important;
|
||||||
|
margin-bottom: var(--ifm-navbar-height) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,173 @@
|
||||||
|
/** Component: Navbar */
|
||||||
|
|
||||||
|
$selector-color-mode-toggle-button: 'button[class*="ColorModeToggle"]';
|
||||||
|
$selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
|
||||||
|
|
||||||
|
:root body {
|
||||||
|
--docsearch-searchbox-background: var(--strapi-neutral-150);
|
||||||
|
--docsearch-searchbox-shadow: 0 0 0 2px var(--strapi-primary-600);
|
||||||
|
--docsearch-muted-color: var(--strapi-neutral-400);
|
||||||
|
--docsearch-text-color: var(--strapi-neutral-400);
|
||||||
|
|
||||||
|
--ifm-navbar-height: 56px;
|
||||||
|
--ifm-navbar-padding-vertical: var(--strapi-spacing-1);
|
||||||
|
--ifm-navbar-padding-horizontal: var(--strapi-spacing-2);
|
||||||
|
--ifm-navbar-shadow: 0 1px 0 0 var(--strapi-neutral-150);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
--custom-navbar-brand-mr: 0;
|
||||||
|
--custom-navbar-icon-color: var(--strapi-neutral-500);
|
||||||
|
--custom-navbar-icon-button-size: 36px;
|
||||||
|
--custom-navbar-icon-button-hover-background: var(--strapi-neutral-100);
|
||||||
|
--custom-navbar-items-font-size: var(--strapi-font-size-sm);
|
||||||
|
--custom-navbar-items-gap: var(--strapi-spacing-3);
|
||||||
|
--custom-navbar-logo-img-width: 40px;
|
||||||
|
--custom-navbar-toggle-mr: var(--strapi-spacing-1);
|
||||||
|
--custom-navbar-transition: all 0.2s ease;
|
||||||
|
|
||||||
|
--ifm-navbar-padding-horizontal: var(--custom-navbar-items-gap);
|
||||||
|
|
||||||
|
transition: var(--custom-navbar-transition);
|
||||||
|
|
||||||
|
&__items {
|
||||||
|
max-width: var(--custom-navbar-items-width);
|
||||||
|
gap: var(--strapi-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__brand,
|
||||||
|
&__logo {
|
||||||
|
height: auto;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__brand {
|
||||||
|
margin-right: var(--custom-navbar-brand-mr);
|
||||||
|
font-size: large;
|
||||||
|
|
||||||
|
@include small-up {
|
||||||
|
font-size: x-large;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__toggle {
|
||||||
|
margin-right: var(--custom-navbar-toggle-mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__logo {
|
||||||
|
margin-right: var(--custom-navbar-items-gap);
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: var(--custom-navbar-logo-img-height);
|
||||||
|
width: var(--custom-navbar-logo-img-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
--ifm-font-weight-semibold: 500;
|
||||||
|
--ifm-navbar-link-hover-color: var(--strapi-neutral-800);
|
||||||
|
|
||||||
|
font-size: var(--custom-navbar-items-font-size);
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
--ifm-font-weight-semibold: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link svg,
|
||||||
|
.navbar-sidebar__close,
|
||||||
|
.DocSearch-Button,
|
||||||
|
#{$selector-color-mode-toggle-button} {
|
||||||
|
color: var(--custom-navbar-icon-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-sidebar__close,
|
||||||
|
.DocSearch-Button,
|
||||||
|
#{$selector-color-mode-toggle-button} {
|
||||||
|
--ifm-color-emphasis-600: currentColor;
|
||||||
|
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--custom-navbar-icon-button-hover-background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__toggle,
|
||||||
|
.navbar-sidebar__close,
|
||||||
|
#{$selector-color-mode-toggle-wrapper} {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: var(--custom-navbar-icon-button-size);
|
||||||
|
width: var(--custom-navbar-icon-button-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.DocSearch-Button {
|
||||||
|
width: var(--custom-navbar-search-button-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include small-up {
|
||||||
|
.navbar {
|
||||||
|
.DocSearch-Button {
|
||||||
|
--custom-navbar-icon-button-hover-background: var(--strapi-neutral-0);
|
||||||
|
|
||||||
|
color: var(--strapi-neutral-400);
|
||||||
|
border: var(--strapi-input-border);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: var(--ifm-font-family-base);
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 var(--strapi-spacing-3);
|
||||||
|
background-color: var(--custom-navbar-icon-button-hover-background);
|
||||||
|
|
||||||
|
svg path {
|
||||||
|
stroke-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-Container {
|
||||||
|
gap: var(--strapi-spacing-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-Placeholder,
|
||||||
|
&-Key {
|
||||||
|
font-size: var(--custom-navbar-items-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-Key {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-Keys {
|
||||||
|
padding: 2px 0 0;
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
.navbar {
|
||||||
|
--custom-navbar-brand-mr: 60px;
|
||||||
|
--custom-navbar-items-gap: var(--strapi-spacing-4);
|
||||||
|
--custom-navbar-search-button-width: 266px;
|
||||||
|
|
||||||
|
--ifm-navbar-padding-horizontal: var(--custom-navbar-items-gap);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
/** Component: Pagination Nav */
|
||||||
|
|
||||||
|
.pagination-nav {
|
||||||
|
--ifm-spacing-horizontal: var(--strapi-spacing-4);
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
&:hover {
|
||||||
|
--ifm-pagination-nav-color-hover: var(--custom-card-border-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
/** Component: Scene */
|
||||||
|
|
||||||
|
#scene {
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/** Component: Search */
|
||||||
|
|
||||||
|
:root body {
|
||||||
|
--docsearch-hit-height: 56px;
|
||||||
|
--docsearch-searchbox-height: 40px;
|
||||||
|
--docsearch-spacing: var(--strapi-spacing-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
body .DocSearch {
|
||||||
|
--custom-search-hit-pb: var(--strapi-spacing-2);
|
||||||
|
|
||||||
|
&-SearchBar {
|
||||||
|
padding-bottom: var(--strapi-spacing-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-Input {
|
||||||
|
--docsearch-text-color: var(--strapi-neutral-800);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-Input,
|
||||||
|
&-Cancel {
|
||||||
|
font-size: var(--strapi-font-size-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-Hit {
|
||||||
|
padding-bottom: var(--custom-search-hit-pb);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,221 @@
|
||||||
|
/** Component: Sidebar / Menu */
|
||||||
|
|
||||||
|
$selector-color-mode-toggle-button: 'button[class*="ColorModeToggle"]';
|
||||||
|
$selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
|
||||||
|
|
||||||
|
:root body {
|
||||||
|
--doc-sidebar-width: 290px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-sidebar {
|
||||||
|
--ifm-navbar-background-color: var(--strapi-neutral-0);
|
||||||
|
|
||||||
|
&__brand {
|
||||||
|
--custom-navbar-sidebar-horizontal-padding: calc(var(--custom-navbar-items-gap) * 2);
|
||||||
|
--ifm-navbar-padding-horizontal:
|
||||||
|
var(--custom-navbar-items-gap)
|
||||||
|
var(--ifm-navbar-padding-vertical)
|
||||||
|
var(--custom-navbar-sidebar-horizontal-padding)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__back {
|
||||||
|
--ifm-menu-color-background-active: var(--strapi-neutral-100);
|
||||||
|
top: -0.95rem;
|
||||||
|
margin-bottom: -0.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__brand {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-sidebar__close,
|
||||||
|
#{$selector-color-mode-toggle-wrapper} {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-sidebar__close {
|
||||||
|
margin-left: initial;
|
||||||
|
padding: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#{$selector-color-mode-toggle-wrapper} {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
--custom-sidebar-caret-size: 1.25rem;
|
||||||
|
--custom-sidebar-menu-font-weight: 400;
|
||||||
|
--custom-sidebar-menu-padding-y: var(--strapi-spacing-4);
|
||||||
|
|
||||||
|
--ifm-menu-color-background-active: transparent;
|
||||||
|
--ifm-menu-color-background-hover: var(--strapi-neutral-100);
|
||||||
|
--ifm-menu-link-padding-vertical: var(--strapi-spacing-1);
|
||||||
|
|
||||||
|
font-weight: var(--custom-sidebar-menu-font-weight);
|
||||||
|
padding-top: var(--custom-sidebar-menu-padding-y) !important;
|
||||||
|
|
||||||
|
&__caret {
|
||||||
|
margin: 0 0 0 3px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
background-size: var(--custom-sidebar-caret-size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__caret,
|
||||||
|
&__caret:before {
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__list {
|
||||||
|
&-item {
|
||||||
|
font-size: var(--custom-sidebar-menu-list-item-font-size, --strapi-font-size-md);
|
||||||
|
|
||||||
|
&-collapsible {
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--ifm-menu-color-background-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
font-weight: 500;
|
||||||
|
min-height: var(--custom-menu-item-link-min-height, 24px);
|
||||||
|
@include transition;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
--ifm-menu-color: var(--strapi-neutral-800);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
--ifm-menu-color-active: var(--strapi-neutral-700);
|
||||||
|
|
||||||
|
font-weight: 700;
|
||||||
|
|
||||||
|
&:not(.menu__link--sublist) {
|
||||||
|
--ifm-menu-color-active: var(--strapi-primary-600);
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
position: absolute;
|
||||||
|
content: " ";
|
||||||
|
width: 5px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: var(--custom-sidebar-menu-list-item-link-active-left, -8px);
|
||||||
|
background-color: var(--strapi-primary-600);
|
||||||
|
border-radius: 0 2px 2px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--sublist-caret {
|
||||||
|
--ifm-menu-color: var(--strapi-neutral-800);
|
||||||
|
--ifm-menu-color-active: var(--strapi-neutral-800);
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--sublist {
|
||||||
|
&.menu__link--with-badge {
|
||||||
|
--custom-menu-link-content-mw: calc(100% - 84px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--with-badge {
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
|
.menu__link__content {
|
||||||
|
max-width: var(--custom-menu-link-content-mw, calc(100% - 56px));
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link__content {
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
margin: -1px 0 -1px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-doc-sidebar {
|
||||||
|
&-item {
|
||||||
|
&-category {
|
||||||
|
&-level-1 {
|
||||||
|
--custom-sidebar-menu-list-item-py: var(--strapi-spacing-1);
|
||||||
|
|
||||||
|
padding-top: var(--custom-sidebar-menu-list-item-py);
|
||||||
|
padding-bottom: var(--custom-sidebar-menu-list-item-py);
|
||||||
|
|
||||||
|
> .menu__list-item-collapsible {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: var(--strapi-font-size-md);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-category, &-link {
|
||||||
|
&-level {
|
||||||
|
&-1 {
|
||||||
|
--custom-sidebar-menu-list-item-font-size: var(--strapi-font-size-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-2 {
|
||||||
|
--custom-sidebar-menu-list-item-font-size: var(--strapi-font-size-sm); // next levels will have this same value
|
||||||
|
--custom-sidebar-menu-list-item-link-active-left: -30px;
|
||||||
|
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-3 {
|
||||||
|
--custom-sidebar-menu-list-item-link-active-left: -42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-4 {
|
||||||
|
--custom-sidebar-menu-list-item-link-active-left: -54px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-5 {
|
||||||
|
--custom-sidebar-menu-list-item-link-active-left: -66px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-doc-sidebar-container {
|
||||||
|
--docusaurus-collapse-button-bg: var(--strapi-neutral-0);
|
||||||
|
--docusaurus-collapse-button-bg-hover: var(--strapi-neutral-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
--ifm-menu-color: var(--strapi-neutral-1000);
|
||||||
|
|
||||||
|
.theme-doc-sidebar-container {
|
||||||
|
.menu {
|
||||||
|
--ifm-menu-color-background-hover: var(--strapi-neutral-100);
|
||||||
|
|
||||||
|
&__link--active {
|
||||||
|
--ifm-menu-color-active: var(--strapi-neutral-800);
|
||||||
|
|
||||||
|
&:not(.menu__link--sublist) {
|
||||||
|
--ifm-menu-color-active: var(--strapi-primary-500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/** Component: Table of Contents */
|
||||||
|
|
||||||
|
.table-of-contents {
|
||||||
|
--custom-toc-py: var(--strapi-spacing-1);
|
||||||
|
--custom-toc-items-py: var(--strapi-spacing-0);
|
||||||
|
|
||||||
|
--ifm-toc-padding-vertical: var(--custom-toc-py);
|
||||||
|
|
||||||
|
font-size: var(--strapi-font-size-xs);
|
||||||
|
|
||||||
|
> li {
|
||||||
|
margin: 0 var(--ifm-toc-padding-horizontal);
|
||||||
|
padding-top: var(--custom-toc-items-py);
|
||||||
|
padding-bottom: var(--custom-toc-items-py);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
--custom-table-of-contents-link-active-before-left: -16px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
@include transition;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&:not(.table-of-contents__link--active) {
|
||||||
|
--ifm-color-primary: var(--strapi-neutral-900);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: var(--custom-table-of-contents-link-active-before-left);
|
||||||
|
width: 3px;
|
||||||
|
border-radius: 0 2px 2px 0;
|
||||||
|
background-color: var(--strapi-primary-600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ul li .table-of-contents {
|
||||||
|
&__link {
|
||||||
|
--custom-table-of-contents-link-active-before-left: -32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: bottom;
|
||||||
|
max-width: 22px;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Responsive */
|
||||||
|
@include medium-up {
|
||||||
|
.table-of-contents {
|
||||||
|
--custom-toc-items-py: var(--strapi-spacing-2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/** Component: Table */
|
||||||
|
table {
|
||||||
|
min-width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
thead {
|
||||||
|
--ifm-table-background: transparent;
|
||||||
|
--ifm-table-stripe-background: transparent;
|
||||||
|
|
||||||
|
tr {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
|
||||||
|
th {
|
||||||
|
--ifm-table-head-background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/** Component: Tab */
|
||||||
|
|
||||||
|
:root body {
|
||||||
|
--custom-tabs-px: var(--strapi-spacing-5);
|
||||||
|
--custom-tabs-py: var(--strapi-spacing-2);
|
||||||
|
|
||||||
|
--ifm-tabs-padding-horizontal: var(--custom-tabs-px);
|
||||||
|
--ifm-tabs-padding-vertical: var(--custom-tabs-py);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
&__item {
|
||||||
|
border-top: 2px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tabs inside Tabs */
|
||||||
|
+ div {
|
||||||
|
[role="tabpanel"] {
|
||||||
|
.tabs {
|
||||||
|
font-size: var(--strapi-font-size-ssm);
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
&--active {
|
||||||
|
--ifm-tabs-color-active-border: transparent;
|
||||||
|
|
||||||
|
background-color: var(--ifm-hover-overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ [class*="margin-top"] {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tabs inside Details component */
|
||||||
|
details {
|
||||||
|
.tabs {
|
||||||
|
--ifm-tabs-color-active-border: var(--strapi-)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/** General: Typography */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--custom-heading-decorative-line-color: var(--strapi-neutral-150);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
--ifm-heading-color: var(--strapi-neutral-900);
|
||||||
|
--ifm-heading-font-weight: 600;
|
||||||
|
--ifm-code-font-size: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, .markdown h1:first-child {
|
||||||
|
--ifm-h1-font-size: 35px;
|
||||||
|
// --ifm-heading-line-height: 24px; // not good
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, .markdown > h2 {
|
||||||
|
--ifm-h2-font-size: 26px;
|
||||||
|
// --ifm-heading-line-height: 24px; // not good
|
||||||
|
}
|
||||||
|
|
||||||
|
h3, .markdown > h3 {
|
||||||
|
--ifm-h3-font-size: var(--strapi-font-size-lg);
|
||||||
|
@include flex-row;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: -10px;
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--custom-heading-decorative-line-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ul {
|
||||||
|
img {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dark mode */
|
||||||
|
@include dark {
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
--ifm-heading-color: var(--strapi-neutral-900);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
import React from 'react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import { ThemeClassNames } from '@docusaurus/theme-common';
|
||||||
|
|
||||||
|
const defaultClassName = ThemeClassNames.common.admonition;
|
||||||
|
const customDefaultProps = {
|
||||||
|
note: {
|
||||||
|
icon: '✏️',
|
||||||
|
title: 'Note',
|
||||||
|
},
|
||||||
|
tip: {
|
||||||
|
icon: '💡',
|
||||||
|
title: 'Tip',
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
icon: '👀',
|
||||||
|
title: 'Info',
|
||||||
|
},
|
||||||
|
caution: {
|
||||||
|
icon: '✋',
|
||||||
|
title: 'Caution',
|
||||||
|
},
|
||||||
|
warning: {
|
||||||
|
icon: '⚠️',
|
||||||
|
title: 'Warning',
|
||||||
|
},
|
||||||
|
danger: {
|
||||||
|
icon: '❗️',
|
||||||
|
title: 'Warning',
|
||||||
|
},
|
||||||
|
strapi: {
|
||||||
|
icon: '🤓',
|
||||||
|
},
|
||||||
|
prerequisites: {
|
||||||
|
icon: '☑️',
|
||||||
|
title: 'Prerequisites',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function CustomAdmonition({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
icon: propIcon,
|
||||||
|
title: propTitle,
|
||||||
|
type,
|
||||||
|
...rest
|
||||||
|
}) {
|
||||||
|
const { icon: defaultIcon, title: defaultTitle } = (customDefaultProps[type] || {});
|
||||||
|
const icon = (propIcon || defaultIcon);
|
||||||
|
const title = (propTitle || defaultTitle);
|
||||||
|
const shouldRenderHeading = !!(icon || title);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
{...rest}
|
||||||
|
className={clsx(
|
||||||
|
defaultClassName,
|
||||||
|
(type && `${defaultClassName}--${type}`),
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{shouldRenderHeading && (
|
||||||
|
<div className={`${defaultClassName}__heading`}>
|
||||||
|
{icon && (
|
||||||
|
<span className={`${defaultClassName}__heading__icon`}>
|
||||||
|
{icon}{' '}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
import React from 'react';
|
||||||
|
// Import the original mapper
|
||||||
|
import MDXComponents from '@theme-original/MDXComponents';
|
||||||
|
/** Import built-in Docusaurus components at the global level
|
||||||
|
* so we don't have to re-import them in every file
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Tabs from '@theme/Tabs';
|
||||||
|
import TabItem from '@theme/TabItem';
|
||||||
|
|
||||||
|
// Import custom components, globally as well
|
||||||
|
import Request from '../components/Request';
|
||||||
|
import Response from '../components/Response';
|
||||||
|
import ApiCall from '../components/ApiCall';
|
||||||
|
import SubtleCallout from '../components/SubtleCallout';
|
||||||
|
import CustomDocCard from '../components/CustomDocCard';
|
||||||
|
import CustomDocCardsWrapper from '../components/CustomDocCardsWrapper';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// Re-use the default mapping
|
||||||
|
...MDXComponents,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components below are imported within the global scope,
|
||||||
|
* meaning you don't have to insert the typical 'import SomeStuff from '/path/to/stuff' line
|
||||||
|
* at the top of a Markdown file before being able to use these components
|
||||||
|
* — see https://docusaurus.io/docs/next/markdown-features/react#mdx-component-scope
|
||||||
|
*/
|
||||||
|
Request,
|
||||||
|
Response,
|
||||||
|
ApiCall,
|
||||||
|
Tabs,
|
||||||
|
TabItem,
|
||||||
|
SubtleCallout,
|
||||||
|
CustomDocCard,
|
||||||
|
CustomDocCardsWrapper,
|
||||||
|
};
|
Binary file not shown.
After Width: | Height: | Size: 164 KiB |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M30.5 6.99998V13C30.5 13.3978 30.342 13.7793 30.0607 14.0606C29.7794 14.3419 29.3978 14.5 29 14.5H23C22.6022 14.5 22.2207 14.3419 21.9394 14.0606C21.6581 13.7793 21.5 13.3978 21.5 13C21.5 12.6022 21.6581 12.2206 21.9394 11.9393C22.2207 11.658 22.6022 11.5 23 11.5H25.1375L22.7625 9.32748C22.7463 9.31248 22.73 9.29748 22.715 9.28123C21.6138 8.18068 20.259 7.36764 18.7697 6.91365C17.2805 6.45967 15.7025 6.37865 14.1746 6.67773C12.6467 6.97681 11.2157 7.64682 10.0076 8.6288C8.79944 9.61079 7.85115 10.8747 7.24616 12.3092C6.64117 13.7437 6.39801 15.305 6.53809 16.8555C6.67817 18.4061 7.19719 19.8985 8.04949 21.2014C8.90178 22.5043 10.0612 23.5777 11.4258 24.3273C12.7904 25.0769 14.3183 25.4796 15.875 25.5H16C18.4249 25.5058 20.7591 24.5784 22.5188 22.91C22.808 22.6366 23.194 22.4894 23.5918 22.5007C23.9896 22.5119 24.3667 22.6807 24.64 22.97C24.9134 23.2592 25.0606 23.6452 25.0493 24.043C25.0381 24.4408 24.8693 24.8179 24.58 25.0912C22.2636 27.2867 19.1916 28.5073 16 28.5H15.8288C13.7826 28.4711 11.7748 27.9404 9.98163 26.9543C8.18848 25.9682 6.66486 24.557 5.54454 22.8445C4.42423 21.132 3.74148 19.1706 3.55626 17.1326C3.37103 15.0946 3.68899 13.0423 4.48222 11.1559C5.27545 9.26953 6.51969 7.60673 8.10567 6.31352C9.69166 5.02032 11.5709 4.13628 13.5784 3.73902C15.5858 3.34176 17.6601 3.44343 19.6191 4.03511C21.5781 4.62679 23.3619 5.69037 24.8138 7.13248L27.5 9.58998V6.99998C27.5 6.60216 27.6581 6.22062 27.9394 5.93932C28.2207 5.65802 28.6022 5.49998 29 5.49998C29.3978 5.49998 29.7794 5.65802 30.0607 5.93932C30.342 6.22062 30.5 6.60216 30.5 6.99998Z" fill="#32324D"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue