Merge branch 'master' into scaffold
@@ -0,0 +1,19 @@
|
||||
# Owners
|
||||
|
||||
- See [CONTRIBUTING.md](CONTRIBUTING.md) for general contribution guidelines.
|
||||
|
||||
## Maintainers 🏓
|
||||
|
||||
- Patrik Oldsberg (@Rugvip, Spotify)
|
||||
- Fredrik Adelöw (@freben, Spotify)
|
||||
- Raghunandan Balachandran (@soapraj, Spotify)
|
||||
- Ben Lambert (@benjdlambert, Spotify)
|
||||
- Marcus Eide (@marcuseide, Spotify)
|
||||
- Niklas Ek (@nikek, Spotify)
|
||||
- Stefan Ålund (@stefanalund, Spotify)
|
||||
- Kat Zhou (@katz95, Spotify)
|
||||
|
||||
## Hall of Fame 👏
|
||||
|
||||
- Andrew Thauer (@andrewthauer, Wealthsimple)
|
||||
- Oliver Sand (@Fox32, SDA-SE)
|
||||
@@ -12,8 +12,8 @@ to? Edit this file
|
||||
|
||||
## Technology
|
||||
|
||||
- [What static site generator is TechDocs using?](./#what-static-site-generator-is-techdocs-using)
|
||||
- [What is the mkdocs-techdocs-core plugin?](./#what-is-the-mkdocs-techdocs-core-plugin)
|
||||
- [What static site generator is TechDocs using?](#what-static-site-generator-is-techdocs-using)
|
||||
- [What is the mkdocs-techdocs-core plugin?](#what-is-the-mkdocs-techdocs-core-plugin)
|
||||
|
||||
#### What static site generator is TechDocs using?
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@ Spotify’s developer experience offering with 2,400+ documentation sites and
|
||||
|
||||
## Project roadmap
|
||||
|
||||
| Version | Description |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [TechDocs V.0 ✅][v0] | Read docs in Backstage - Enable anyone to get a reader experience working in Backstage. [See V.0 Use Cases.](./#techdocs-v0) |
|
||||
| [TechDocs V.1 🚧][v1] | TechDocs end to end (alpha) - Alpha of TechDocs that you can use end to end - and contribute to. [See V.1 Use Cases.](./#techdocs-v1) |
|
||||
| [TechDocs V.2 🔮⌛][v2] | Platform stability and compatibility improvements. [See V.2 Use Cases.](./#techdocs-v2) |
|
||||
| TechDocs V.3 🔮⌛ | Widget Architecture - TechDocs widget architecture available, so the community can create their own customized features. |
|
||||
| Version | Description |
|
||||
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [TechDocs V.0 ✅][v0] | Read docs in Backstage - Enable anyone to get a reader experience working in Backstage. [See V.0 Use Cases.](#techdocs-v0) |
|
||||
| [TechDocs V.1 🚧][v1] | TechDocs end to end (alpha) - Alpha of TechDocs that you can use end to end - and contribute to. [See V.1 Use Cases.](#techdocs-v1) |
|
||||
| [TechDocs V.2 🔮⌛][v2] | Platform stability and compatibility improvements. [See V.2 Use Cases.](#techdocs-v2) |
|
||||
| TechDocs V.3 🔮⌛ | Widget Architecture - TechDocs widget architecture available, so the community can create their own customized features. |
|
||||
|
||||
[v0]: https://github.com/spotify/backstage/milestone/15
|
||||
[v1]: https://github.com/spotify/backstage/milestone/16
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: logos
|
||||
title: Logos
|
||||
sidebar_label: Logo assets
|
||||
---
|
||||
|
||||
Guidelines for how to use the Backstage logo and icon can be found
|
||||
[here](/logo_assets/Backstage_Identity_Assets_Overview.pdf). The assets below
|
||||
are all in `.svg` format. Other formats are available in the
|
||||
[repository](https://github.com/spotify/backstage/tree/master/microsite/static/logo_assets).
|
||||
|
||||
## Backstage logo
|
||||
|
||||
<a href="/logo_assets/svg/Logo_White.svg">
|
||||
<img src="/logo_assets/svg/Logo_White.svg" width="600" />
|
||||
</a>
|
||||
|
||||
<a href="/logo_assets/svg/Logo_Teal.svg">
|
||||
<img src="/logo_assets/svg/Logo_Teal.svg" width="600" />
|
||||
</a>
|
||||
|
||||
<a href="/logo_assets/svg/Logo_Black.svg">
|
||||
<img src="/logo_assets/svg/Logo_Black.svg" width="600" style="background-color:white" />
|
||||
</a>
|
||||
|
||||
## Backstage icon
|
||||
|
||||
<div>
|
||||
<a href="/logo_assets/svg/Icon_White.svg">
|
||||
<img src="/logo_assets/svg/Icon_White.svg" width="180" height="180" />
|
||||
</a>
|
||||
<a href="/logo_assets/svg/Icon_Teal.svg">
|
||||
<img src="/logo_assets/svg/Icon_Teal.svg" width="180" height="180" />
|
||||
</a>
|
||||
<a href="/logo_assets/svg/Icon_Gradient.svg">
|
||||
<img src="/logo_assets/svg/Icon_Gradient.svg" width="180" height="180" />
|
||||
</a>
|
||||
<a href="/logo_assets/svg/Icon_Black.svg">
|
||||
<img src="/logo_assets/svg/Icon_Black.svg" width="180" height="180" style="background-color:white" />
|
||||
</a>
|
||||
</div>
|
||||
@@ -53,6 +53,11 @@ async function verifyUrl(basePath, url) {
|
||||
return { url, basePath, problem: 'not-relative' };
|
||||
}
|
||||
|
||||
const staticPath = resolvePath(projectRoot, 'microsite/static', `.${url}`);
|
||||
if (await fs.pathExists(staticPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
path = resolvePath(projectRoot, `.${url}`);
|
||||
} else {
|
||||
path = resolvePath(dirname(resolvePath(projectRoot, basePath)), url);
|
||||
@@ -103,7 +108,9 @@ async function main() {
|
||||
console.log(`Found ${badUrls.length} bad links within repo`);
|
||||
for (const { url, basePath, problem } of badUrls) {
|
||||
if (problem === 'missing') {
|
||||
console.error(`Unable to reach ${url}, linked from ${basePath}`);
|
||||
console.error(
|
||||
`Unable to reach ${url} from root or microsite/static/, linked from ${basePath}`,
|
||||
);
|
||||
} else if (problem === 'not-relative') {
|
||||
console.error('Links to /docs/ must be relative');
|
||||
console.error(` From: ${basePath}`);
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
"overview/roadmap",
|
||||
"overview/vision",
|
||||
"overview/background",
|
||||
"overview/adopting"
|
||||
"overview/adopting",
|
||||
"overview/logos"
|
||||
],
|
||||
"Getting Started": [
|
||||
"getting-started/index",
|
||||
|
||||
@@ -93,8 +93,10 @@ const siteConfig = {
|
||||
cleanUrl: true,
|
||||
|
||||
// Open Graph and Twitter card images.
|
||||
ogImage: 'img/logo-gradient-on-dark.svg',
|
||||
twitterImage: 'img/logo-gradient-on-dark.svg',
|
||||
ogImage:
|
||||
'logo_assets/png/Backstage_Identity_Assets_Artwork_RGB_04_Icon_Teal.png',
|
||||
twitterImage:
|
||||
'logo_assets/png/Backstage_Identity_Assets_Artwork_RGB_04_Icon_Teal.png',
|
||||
|
||||
// For sites with a sizable amount of content, set collapsible to true.
|
||||
// Expand/collapse the links and subcategories under categories.
|
||||
|
||||
|
After Width: | Height: | Size: 299 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 197 KiB |
@@ -0,0 +1 @@
|
||||
<svg id="Assets" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 337.46 428.5"><defs><style>.cls-1{fill:#121212;}</style></defs><title>06 Icon_Black</title><path class="cls-1" d="M303,166.05a80.69,80.69,0,0,0,13.45-10.37c.79-.77,1.55-1.53,2.3-2.3a83.12,83.12,0,0,0,7.93-9.38A63.69,63.69,0,0,0,333,133.23a48.58,48.58,0,0,0,4.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56,0,78.3,115.23,0,190.25l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.69,19.16-18.36,25.52-42.12,13.7-61.87a49.22,49.22,0,0,0-6.8-8.87A89.17,89.17,0,0,0,259,178.29h.15a85.08,85.08,0,0,0,31-5.79A80.88,80.88,0,0,0,303,166.05ZM202.45,225.86c-19.32,18.51-50.4,21.23-75.7,5.9L51.61,186.15l67.45-64.64,76.41,46.38C223,184.58,221.49,207.61,202.45,225.86Zm8.93-82.22-70.65-42.89L205.14,39,274.51,81.1c25.94,15.72,29.31,37,10.55,55A60.69,60.69,0,0,1,211.38,143.64Zm29.86,190c-19.57,18.75-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,282.52v24.67L108.6,373.1a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.27,87.27,0,0,1,241.24,333.68Zm0-39c-19.57,18.75-46.17,29.08-74.88,29.08a123.81,123.81,0,0,1-64.1-18.19L0,243.53v24.68l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.5v-1.78A87.27,87.27,0,0,1,241.24,294.7Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.81,123.81,0,0,1-64.1-18.19L0,204.55v24.68l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.68,12.88-12.35,20-27.13,19.68-41.5v-1.82A86.09,86.09,0,0,1,241.24,255.71Zm83.7,25.74a94.15,94.15,0,0,1-60.2,25.86h0V334a81.6,81.6,0,0,0,51.74-22.37c14-13.38,21.14-28.11,21-42.64v-2.19A94.92,94.92,0,0,1,324.94,281.45Zm-83.7,91.21c-19.57,18.76-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,321.5v24.68l108.6,65.9a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.8,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A86.29,86.29,0,0,1,241.24,372.66ZM327,162.45c-.68.69-1.35,1.38-2.05,2.06a94.37,94.37,0,0,1-10.64,8.65,91.35,91.35,0,0,1-11.6,7,94.53,94.53,0,0,1-26.24,8.71,97.69,97.69,0,0,1-14.16,1.57c.5,1.61.9,3.25,1.25,4.9a53.27,53.27,0,0,1,1.14,12V217h.05a84.41,84.41,0,0,0,25.35-5.55,81,81,0,0,0,26.39-16.82c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,172.17a48.55,48.55,0,0,0,4.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08,1.54-2.25,3.09A96.73,96.73,0,0,1,327,162.45Zm0,77.92c-.69.7-1.31,1.41-2,2.1a94.2,94.2,0,0,1-60.2,25.86h0l0,26.67h0a81.6,81.6,0,0,0,51.74-22.37A73.51,73.51,0,0,0,333,250.13a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74,1.07-1.46,2.15-2.27,3.21A95.68,95.68,0,0,1,327,240.37Zm0-39c-.69.7-1.31,1.41-2,2.1a93.18,93.18,0,0,1-10.63,8.65,91.63,91.63,0,0,1-11.63,7,95.47,95.47,0,0,1-37.94,10.18h0V256h0a81.65,81.65,0,0,0,51.74-22.37c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,211.15a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74,1.08-1.46,2.16-2.27,3.22A95.68,95.68,0,0,1,327,201.39Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg id="Assets" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 982.38 1247.39"><defs><style>.cls-1{fill:url(#linear-gradient);}</style><linearGradient id="linear-gradient" x1="392.22" y1="1235.97" x2="609.18" y2="5.5" gradientUnits="userSpaceOnUse"><stop offset="0.07" stop-color="#36baa2"/><stop offset="0.34" stop-color="#61ddc8"/><stop offset="0.53" stop-color="#7df3e1"/></linearGradient></defs><title>07 Large Icon_Gradient</title><path class="cls-1" d="M702.28,857.87c-57,54.61-134.4,84.68-218,84.68-64.94,0-129.45-18.31-186.61-53L0,708.94v71.84L316.14,972.65c53.11,32.19,111.56,47.78,168.15,47.78,72.55,0,142.06-25.62,193.35-74.77,37.49-35.93,58.2-79,57.29-120.8v-5.2A253.66,253.66,0,0,1,702.28,857.87Zm0-113.47c-57,54.6-134.4,84.68-218,84.68-64.94,0-129.45-18.32-186.61-53L0,595.47V667.3L316.14,859.16C369.25,891.36,427.7,907,484.29,907c72.55,0,142.06-25.62,193.35-74.77,37.49-35.93,58.2-79,57.29-120.79v-5.31A252.11,252.11,0,0,1,702.28,744.4Zm0,227c-57,54.6-134.4,84.68-218,84.68-64.94,0-129.45-18.32-186.61-53L0,822.42v71.84l316.14,191.86c53.11,32.2,111.56,47.79,168.15,47.79,72.55,0,142.06-25.63,193.35-74.78,37.49-35.92,58.2-79,57.29-120.78v-5.22A253.79,253.79,0,0,1,702.28,971.36Zm0,113.48c-57,54.6-134.4,84.68-218,84.68-64.94,0-129.45-18.32-186.61-53L0,935.9v71.84L316.14,1199.6c53.11,32.2,111.56,47.79,168.15,47.79,72.55,0,142.06-25.62,193.35-74.78,37.49-35.92,58.2-79,57.29-120.78v-5.21A253.73,253.73,0,0,1,702.28,1084.84ZM951.79,586.27c-2,2-3.79,4.1-5.88,6.09A283.08,283.08,0,0,1,881.13,638a278.45,278.45,0,0,1-110.44,29.63h-.15l0,77.63h.11C825,741.78,878.61,721,921.28,680.14c2.33-2.24,4.38-4.54,6.59-6.8A239.4,239.4,0,0,0,951,646a185,185,0,0,0,18.29-31.37,141.27,141.27,0,0,0,12.57-47.87c.27-3.6.6-7.2.56-10.79v-6.38c-2.17,3.12-4.26,6.26-6.61,9.36A284.07,284.07,0,0,1,951.79,586.27Zm.1-113.36c-2,2-3.92,4-6,6a288.89,288.89,0,0,1-64.72,45.66,276.05,276.05,0,0,1-76.4,25.37,287,287,0,0,1-41.23,4.55c1.48,4.7,2.63,9.47,3.64,14.27a155,155,0,0,1,3.32,34.94v28.1h.16a245.44,245.44,0,0,0,73.78-16.15,235.88,235.88,0,0,0,76.81-49c2.33-2.24,4.38-4.53,6.59-6.8A237.77,237.77,0,0,0,951,532.55a184.13,184.13,0,0,0,18.29-31.36,141.22,141.22,0,0,0,12.57-47.86c.27-3.6.6-7.2.56-10.8v-6c-2.09,3-4.29,6-6.56,9A285.06,285.06,0,0,1,951.89,472.91Zm-.1,226.84c-2,2-3.8,4.09-5.88,6.09C898.8,751,837.08,777.38,770.69,781.11h-.09l0,77.63h.06c54.26-3.48,107.92-24.23,150.59-65.12,21.84-20.92,37.77-43,48-65.47a141.28,141.28,0,0,0,12.57-47.86c.27-3.61.6-7.21.56-10.8V663.1c-2.17,3.13-4.26,6.27-6.61,9.36A283,283,0,0,1,951.79,699.75ZM770.69,894.59h0l0,77.63C825,968.74,878.61,948,921.28,907.1c40.67-39,61.55-81.83,61.09-124.13v-6.4a276.79,276.79,0,0,1-36.46,42.76C898.79,864.47,837.08,890.86,770.69,894.59ZM878.3,182.25,578,0,227.93,335.43,0,553.82,316.14,745.68c53.11,32.2,111.56,47.79,168.15,47.79,72.55,0,142.06-25.62,193.35-74.77,55.78-53.45,74.29-122.64,39.87-180.11a142.23,142.23,0,0,0-19.79-25.82A260,260,0,0,0,753.87,519h.43a247.6,247.6,0,0,0,90.17-16.86,235.71,235.71,0,0,0,76.81-49c2.32-2.21,4.52-4.45,6.7-6.69a238.54,238.54,0,0,0,23.08-27.3,184.08,184.08,0,0,0,18.25-31.34A141.52,141.52,0,0,0,982,340.11C986.32,283.66,953,227.53,878.3,182.25Zm-289,475.23C533.09,711.36,442.61,719.3,369,674.66L150.25,541.89,346.58,353.71,569,488.74C649.19,537.34,644.77,604.36,589.33,657.48Zm240.5-261.25C776,447.8,689,462.79,615.33,418.14L409.67,293.29l187.5-179.81L799.11,236.07C874.62,281.85,884.43,343.9,829.83,396.23Z"/></svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1 @@
|
||||
<svg id="Assets" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 337.46 428.5"><defs><style>.cls-1{fill:#7df3e1;}</style></defs><title>04 Icon_Teal</title><path class="cls-1" d="M303,166.05a80.69,80.69,0,0,0,13.45-10.37c.79-.77,1.55-1.53,2.3-2.3a83.12,83.12,0,0,0,7.93-9.38A63.69,63.69,0,0,0,333,133.23a48.58,48.58,0,0,0,4.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56,0,78.3,115.23,0,190.25l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.69,19.16-18.36,25.52-42.12,13.7-61.87a49.22,49.22,0,0,0-6.8-8.87A89.17,89.17,0,0,0,259,178.29h.15a85.08,85.08,0,0,0,31-5.79A80.88,80.88,0,0,0,303,166.05ZM202.45,225.86c-19.32,18.51-50.4,21.23-75.7,5.9L51.61,186.15l67.45-64.64,76.41,46.38C223,184.58,221.49,207.61,202.45,225.86Zm8.93-82.22-70.65-42.89L205.14,39,274.51,81.1c25.94,15.72,29.31,37,10.55,55A60.69,60.69,0,0,1,211.38,143.64Zm29.86,190c-19.57,18.75-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,282.52v24.67L108.6,373.1a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.27,87.27,0,0,1,241.24,333.68Zm0-39c-19.57,18.75-46.17,29.08-74.88,29.08a123.81,123.81,0,0,1-64.1-18.19L0,243.53v24.68l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.5v-1.78A87.27,87.27,0,0,1,241.24,294.7Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.81,123.81,0,0,1-64.1-18.19L0,204.55v24.68l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.68,12.88-12.35,20-27.13,19.68-41.5v-1.82A86.09,86.09,0,0,1,241.24,255.71Zm83.7,25.74a94.15,94.15,0,0,1-60.2,25.86h0V334a81.6,81.6,0,0,0,51.74-22.37c14-13.38,21.14-28.11,21-42.64v-2.19A94.92,94.92,0,0,1,324.94,281.45Zm-83.7,91.21c-19.57,18.76-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,321.5v24.68l108.6,65.9a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.8,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A86.29,86.29,0,0,1,241.24,372.66ZM327,162.45c-.68.69-1.35,1.38-2.05,2.06a94.37,94.37,0,0,1-10.64,8.65,91.35,91.35,0,0,1-11.6,7,94.53,94.53,0,0,1-26.24,8.71,97.69,97.69,0,0,1-14.16,1.57c.5,1.61.9,3.25,1.25,4.9a53.27,53.27,0,0,1,1.14,12V217h.05a84.41,84.41,0,0,0,25.35-5.55,81,81,0,0,0,26.39-16.82c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,172.17a48.55,48.55,0,0,0,4.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08,1.54-2.25,3.09A96.73,96.73,0,0,1,327,162.45Zm0,77.92c-.69.7-1.31,1.41-2,2.1a94.2,94.2,0,0,1-60.2,25.86h0l0,26.67h0a81.6,81.6,0,0,0,51.74-22.37A73.51,73.51,0,0,0,333,250.13a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74,1.07-1.46,2.15-2.27,3.21A95.68,95.68,0,0,1,327,240.37Zm0-39c-.69.7-1.31,1.41-2,2.1a93.18,93.18,0,0,1-10.63,8.65,91.63,91.63,0,0,1-11.63,7,95.47,95.47,0,0,1-37.94,10.18h0V256h0a81.65,81.65,0,0,0,51.74-22.37c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,211.15a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74,1.08-1.46,2.16-2.27,3.22A95.68,95.68,0,0,1,327,201.39Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg id="Assets" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 337.46 428.5"><defs><style>.cls-1{fill:#fff;}</style></defs><title>02 Icon_White</title><path class="cls-1" d="M303,166.05a80.69,80.69,0,0,0,13.45-10.37c.79-.77,1.55-1.53,2.3-2.3a83.12,83.12,0,0,0,7.93-9.38A63.69,63.69,0,0,0,333,133.23a48.58,48.58,0,0,0,4.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56,0,78.3,115.23,0,190.25l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.69,19.16-18.36,25.52-42.12,13.7-61.87a49.22,49.22,0,0,0-6.8-8.87A89.17,89.17,0,0,0,259,178.29h.15a85.08,85.08,0,0,0,31-5.79A80.88,80.88,0,0,0,303,166.05ZM202.45,225.86c-19.32,18.51-50.4,21.23-75.7,5.9L51.61,186.15l67.45-64.64,76.41,46.38C223,184.58,221.49,207.61,202.45,225.86Zm8.93-82.22-70.65-42.89L205.14,39,274.51,81.1c25.94,15.72,29.31,37,10.55,55A60.69,60.69,0,0,1,211.38,143.64Zm29.86,190c-19.57,18.75-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,282.52v24.67L108.6,373.1a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.27,87.27,0,0,1,241.24,333.68Zm0-39c-19.57,18.75-46.17,29.08-74.88,29.08a123.81,123.81,0,0,1-64.1-18.19L0,243.53v24.68l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.5v-1.78A87.27,87.27,0,0,1,241.24,294.7Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.81,123.81,0,0,1-64.1-18.19L0,204.55v24.68l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.68,12.88-12.35,20-27.13,19.68-41.5v-1.82A86.09,86.09,0,0,1,241.24,255.71Zm83.7,25.74a94.15,94.15,0,0,1-60.2,25.86h0V334a81.6,81.6,0,0,0,51.74-22.37c14-13.38,21.14-28.11,21-42.64v-2.19A94.92,94.92,0,0,1,324.94,281.45Zm-83.7,91.21c-19.57,18.76-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,321.5v24.68l108.6,65.9a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.8,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A86.29,86.29,0,0,1,241.24,372.66ZM327,162.45c-.68.69-1.35,1.38-2.05,2.06a94.37,94.37,0,0,1-10.64,8.65,91.35,91.35,0,0,1-11.6,7,94.53,94.53,0,0,1-26.24,8.71,97.69,97.69,0,0,1-14.16,1.57c.5,1.61.9,3.25,1.25,4.9a53.27,53.27,0,0,1,1.14,12V217h.05a84.41,84.41,0,0,0,25.35-5.55,81,81,0,0,0,26.39-16.82c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,172.17a48.55,48.55,0,0,0,4.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08,1.54-2.25,3.09A96.73,96.73,0,0,1,327,162.45Zm0,77.92c-.69.7-1.31,1.41-2,2.1a94.2,94.2,0,0,1-60.2,25.86h0l0,26.67h0a81.6,81.6,0,0,0,51.74-22.37A73.51,73.51,0,0,0,333,250.13a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74,1.07-1.46,2.15-2.27,3.21A95.68,95.68,0,0,1,327,240.37Zm0-39c-.69.7-1.31,1.41-2,2.1a93.18,93.18,0,0,1-10.63,8.65,91.63,91.63,0,0,1-11.63,7,95.47,95.47,0,0,1-37.94,10.18h0V256h0a81.65,81.65,0,0,0,51.74-22.37c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,211.15a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74,1.08-1.46,2.16-2.27,3.22A95.68,95.68,0,0,1,327,201.39Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
@@ -10,6 +10,7 @@ nav:
|
||||
- Vision: 'overview/vision.md'
|
||||
- The Spotify story: 'overview/background.md'
|
||||
- Strategies for adopting: 'overview/adopting.md'
|
||||
- Logo assets: 'overview/logos.md'
|
||||
- Getting started:
|
||||
- Running Backstage locally: 'getting-started/index.md'
|
||||
- Installation: 'getting-started/installation.md'
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"@spotify/eslint-config": "^7.0.1",
|
||||
"@sucrase/webpack-loader": "^2.0.0",
|
||||
"@svgr/plugin-jsx": "5.4.x",
|
||||
"@svgr/plugin-svgo": "4.3.x",
|
||||
"@svgr/plugin-svgo": "5.4.x",
|
||||
"@svgr/rollup": "5.4.x",
|
||||
"@svgr/webpack": "5.4.x",
|
||||
"@types/start-server-webpack-plugin": "^2.2.0",
|
||||
|
||||
@@ -86,3 +86,9 @@ export const Languages = () => (
|
||||
<CodeSnippet text={PYTHON} language="python" showLineNumbers />
|
||||
</InfoCard>
|
||||
);
|
||||
|
||||
export const CopyCode = () => (
|
||||
<InfoCard title="Copy Code">
|
||||
<CodeSnippet text={JAVASCRIPT} language="javascript" showCopyCodeButton />
|
||||
</InfoCard>
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
|
||||
import { CodeSnippet } from './CodeSnippet';
|
||||
@@ -55,4 +55,14 @@ describe('<CodeSnippet />', () => {
|
||||
expect(queryByText(/2/)).toBeInTheDocument();
|
||||
expect(queryByText(/3/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('copy code using button', async () => {
|
||||
document.execCommand = jest.fn();
|
||||
const rendered = render(
|
||||
wrapInTestApp(<CodeSnippet {...minProps} showCopyCodeButton />),
|
||||
);
|
||||
const button = rendered.getByTitle('Text copied to clipboard');
|
||||
fireEvent.click(button);
|
||||
expect(document.execCommand).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,19 +20,22 @@ import SyntaxHighlighter from 'react-syntax-highlighter';
|
||||
import { docco, dark } from 'react-syntax-highlighter/dist/cjs/styles/hljs';
|
||||
import { useTheme } from '@material-ui/core';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { CopyTextButton } from '../CopyTextButton';
|
||||
|
||||
type Props = {
|
||||
text: string;
|
||||
language: string;
|
||||
showLineNumbers?: boolean;
|
||||
showCopyCodeButton?: boolean;
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
showLineNumbers: false,
|
||||
showCopyCodeButton: false,
|
||||
};
|
||||
|
||||
export const CodeSnippet: FC<Props> = props => {
|
||||
const { text, language, showLineNumbers } = {
|
||||
const { text, language, showLineNumbers, showCopyCodeButton } = {
|
||||
...defaultProps,
|
||||
...props,
|
||||
};
|
||||
@@ -41,13 +44,20 @@ export const CodeSnippet: FC<Props> = props => {
|
||||
const mode = theme.palette.type === 'dark' ? dark : docco;
|
||||
|
||||
return (
|
||||
<SyntaxHighlighter
|
||||
language={language}
|
||||
style={mode}
|
||||
showLineNumbers={showLineNumbers}
|
||||
>
|
||||
{text}
|
||||
</SyntaxHighlighter>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<SyntaxHighlighter
|
||||
language={language}
|
||||
style={mode}
|
||||
showLineNumbers={showLineNumbers}
|
||||
>
|
||||
{text}
|
||||
</SyntaxHighlighter>
|
||||
{showCopyCodeButton && (
|
||||
<div style={{ position: 'absolute', top: 0, right: 0 }}>
|
||||
<CopyTextButton text={text} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -56,4 +66,5 @@ CodeSnippet.propTypes = {
|
||||
text: PropTypes.string.isRequired,
|
||||
language: PropTypes.string.isRequired,
|
||||
showLineNumbers: PropTypes.bool,
|
||||
showCopyCodeButton: PropTypes.bool,
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { CopyTextButton } from './CopyTextButton';
|
||||
import {
|
||||
@@ -76,7 +76,7 @@ describe('<CopyTextButton />', () => {
|
||||
),
|
||||
);
|
||||
const button = rendered.getByTitle('mockTooltip');
|
||||
button.click();
|
||||
fireEvent.click(button);
|
||||
expect(document.execCommand).toHaveBeenCalled();
|
||||
rendered.getByText('mockTooltip');
|
||||
});
|
||||
|
||||
@@ -63,7 +63,7 @@ export const CopyTextButton: FC<Props> = props => {
|
||||
};
|
||||
const classes = useStyles(props);
|
||||
const errorApi = useApi(errorApiRef);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const inputRef = useRef<HTMLTextAreaElement>(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const handleCopyClick: MouseEventHandler = e => {
|
||||
@@ -82,9 +82,8 @@ export const CopyTextButton: FC<Props> = props => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
<textarea
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
style={{ position: 'absolute', top: -9999, left: 9999 }}
|
||||
defaultValue={text}
|
||||
/>
|
||||
|
||||
@@ -2,8 +2,15 @@ FROM node:12
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY . .
|
||||
# Copy repo skeleton first, to avoid unnecessary docker cache invalidation.
|
||||
# The skeleton contains the package.json of each package in the monorepo,
|
||||
# and along with yarn.lock and the root package.json, that's enough to run yarn install.
|
||||
ADD yarn.lock package.json skeleton.tar ./
|
||||
|
||||
RUN yarn install --frozen-lockfile --production
|
||||
|
||||
# This will copy the contents of the dist-workspace when running the build-image command.
|
||||
# Do not use this Dockerfile outside of that command, as it will copy in the source code instead.
|
||||
COPY . .
|
||||
|
||||
CMD ["node", "packages/backend"]
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
AnyApiFactory,
|
||||
} from '@backstage/core';
|
||||
import SentimentDissatisfiedIcon from '@material-ui/icons/SentimentDissatisfied';
|
||||
import { Routes } from 'react-router';
|
||||
|
||||
// TODO(rugvip): export proper plugin type from core that isn't the plugin class
|
||||
type BackstagePlugin = ReturnType<typeof createPlugin>;
|
||||
@@ -97,7 +98,7 @@ class DevAppBuilder {
|
||||
<AppRouter>
|
||||
<SidebarPage>
|
||||
{sidebar}
|
||||
{deprecatedAppRoutes}
|
||||
<Routes>{deprecatedAppRoutes}</Routes>
|
||||
</SidebarPage>
|
||||
</AppRouter>
|
||||
</AppProvider>
|
||||
|
||||
@@ -39,7 +39,7 @@ export const EntityPageApi: FC<{ entity: Entity }> = ({ entity }) => {
|
||||
<Grid container spacing={3}>
|
||||
{apiNames.map(api => (
|
||||
<Grid item xs={12} key={api}>
|
||||
<ApiDefinitionCard title={api} apiEntity={apiEntities!.get(api)} />
|
||||
<ApiDefinitionCard apiEntity={apiEntities!.get(api)} />
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
|
||||
@@ -15,31 +15,92 @@
|
||||
*/
|
||||
|
||||
import { ApiEntity } from '@backstage/catalog-model';
|
||||
import { InfoCard } from '@backstage/core';
|
||||
import { TabbedCard, CardTab } from '@backstage/core';
|
||||
import React from 'react';
|
||||
import { ApiDefinitionWidget } from '../ApiDefinitionWidget';
|
||||
import { PlainApiDefinitionWidget } from '../PlainApiDefinitionWidget';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import { OpenApiDefinitionWidget } from '../OpenApiDefinitionWidget';
|
||||
import { AsyncApiDefinitionWidget } from '../AsyncApiDefinitionWidget';
|
||||
|
||||
type Props = {
|
||||
title?: string;
|
||||
apiEntity?: ApiEntity;
|
||||
type ApiDefinitionWidget = {
|
||||
type: string;
|
||||
title: string;
|
||||
component: (definition: string) => React.ReactElement;
|
||||
rawLanguage?: string;
|
||||
};
|
||||
|
||||
export const ApiDefinitionCard = ({ title, apiEntity }: Props) => {
|
||||
export function defaultDefinitionWidgets(): ApiDefinitionWidget[] {
|
||||
return [
|
||||
{
|
||||
type: 'openapi',
|
||||
title: 'OpenAPI',
|
||||
rawLanguage: 'yaml',
|
||||
component: definition => (
|
||||
<OpenApiDefinitionWidget definition={definition} />
|
||||
),
|
||||
},
|
||||
{
|
||||
type: 'asyncapi',
|
||||
title: 'AsyncAPI',
|
||||
rawLanguage: 'yaml',
|
||||
component: definition => (
|
||||
<AsyncApiDefinitionWidget definition={definition} />
|
||||
),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
type Props = {
|
||||
apiEntity?: ApiEntity;
|
||||
definitionWidgets?: ApiDefinitionWidget[];
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
definitionWidgets: defaultDefinitionWidgets(),
|
||||
};
|
||||
|
||||
export const ApiDefinitionCard = (props: Props) => {
|
||||
const { apiEntity, definitionWidgets } = {
|
||||
...defaultProps,
|
||||
...props,
|
||||
};
|
||||
|
||||
if (!apiEntity) {
|
||||
return <Alert severity="error">Could not fetch the API</Alert>;
|
||||
}
|
||||
|
||||
const definitionWidget = definitionWidgets.find(
|
||||
d => d.type === apiEntity.spec.type,
|
||||
);
|
||||
|
||||
if (definitionWidget) {
|
||||
return (
|
||||
<InfoCard title={title}>
|
||||
<Alert severity="error">Could not fetch the API</Alert>
|
||||
</InfoCard>
|
||||
<TabbedCard title={apiEntity.metadata.name}>
|
||||
<CardTab label={definitionWidget.title}>
|
||||
{definitionWidget.component(apiEntity.spec.definition)}
|
||||
</CardTab>
|
||||
<CardTab label="Raw">
|
||||
<PlainApiDefinitionWidget
|
||||
definition={apiEntity.spec.definition}
|
||||
language={definitionWidget.rawLanguage || apiEntity.spec.type}
|
||||
/>
|
||||
</CardTab>
|
||||
</TabbedCard>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<InfoCard title={title} subheader={apiEntity.spec.type}>
|
||||
<ApiDefinitionWidget
|
||||
type={apiEntity.spec.type}
|
||||
definition={apiEntity.spec.definition}
|
||||
/>
|
||||
</InfoCard>
|
||||
<TabbedCard
|
||||
title={apiEntity.metadata.name}
|
||||
children={[
|
||||
// Has to be an array, otherwise typescript doesn't like that this has only a single child
|
||||
<CardTab label={apiEntity.spec.type}>
|
||||
<PlainApiDefinitionWidget
|
||||
definition={apiEntity.spec.definition}
|
||||
language={apiEntity.spec.type}
|
||||
/>
|
||||
</CardTab>,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { AsyncApiDefinitionWidget } from '../AsyncApiDefinitionWidget';
|
||||
import { OpenApiDefinitionWidget } from '../OpenApiDefinitionWidget';
|
||||
import { PlainApiDefinitionWidget } from '../PlainApiDefinitionWidget';
|
||||
|
||||
type Props = {
|
||||
type: string;
|
||||
definition: string;
|
||||
};
|
||||
|
||||
export const ApiDefinitionWidget = ({ type, definition }: Props) => {
|
||||
switch (type) {
|
||||
case 'openapi':
|
||||
return <OpenApiDefinitionWidget definition={definition} />;
|
||||
|
||||
case 'asyncapi':
|
||||
return <AsyncApiDefinitionWidget definition={definition} />;
|
||||
|
||||
default:
|
||||
return (
|
||||
<PlainApiDefinitionWidget definition={definition} language={type} />
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { ApiDefinitionWidget } from './ApiDefinitionWidget';
|
||||
@@ -136,7 +136,7 @@ const useStyles = makeStyles(theme => ({
|
||||
}));
|
||||
|
||||
type Props = {
|
||||
definition: any;
|
||||
definition: string;
|
||||
};
|
||||
|
||||
export const AsyncApiDefinitionWidget = ({ definition }: Props) => {
|
||||
|
||||
@@ -66,7 +66,7 @@ const useStyles = makeStyles(theme => ({
|
||||
}));
|
||||
|
||||
type Props = {
|
||||
definition: any;
|
||||
definition: string;
|
||||
};
|
||||
|
||||
export const OpenApiDefinitionWidget = ({ definition }: Props) => {
|
||||
|
||||
@@ -23,5 +23,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export const PlainApiDefinitionWidget = ({ definition, language }: Props) => {
|
||||
return <CodeSnippet text={definition} language={language} />;
|
||||
return (
|
||||
<CodeSnippet text={definition} language={language} showCopyCodeButton />
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,5 +15,8 @@
|
||||
*/
|
||||
|
||||
export { ApiDefinitionCard } from './ApiDefinitionCard';
|
||||
export { AsyncApiDefinitionWidget } from './AsyncApiDefinitionWidget';
|
||||
export { OpenApiDefinitionWidget } from './OpenApiDefinitionWidget';
|
||||
export { PlainApiDefinitionWidget } from './PlainApiDefinitionWidget';
|
||||
export { useComponentApiNames } from './useComponentApiNames';
|
||||
export { useComponentApiEntities } from './useComponentApiEntities';
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.45",
|
||||
"classnames": "^2.2.6",
|
||||
"moment": "^2.26.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
|
||||
@@ -102,6 +102,9 @@ export function AboutCard({ entity }: AboutCardProps) {
|
||||
<nav className={classes.links}>
|
||||
<IconLinkVertical label="View Source" {...codeLink} />
|
||||
<IconLinkVertical
|
||||
disabled={
|
||||
!entity.metadata.annotations?.['backstage.io/techdocs-ref']
|
||||
}
|
||||
label="View Techdocs"
|
||||
icon={<DocsIcon />}
|
||||
href={`/docs/${entity.kind}:${entity.metadata.namespace ?? ''}:${
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import * as React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { makeStyles, Link } from '@material-ui/core';
|
||||
import LinkIcon from '@material-ui/icons/Link';
|
||||
|
||||
export type IconLinkVerticalProps = {
|
||||
icon?: React.ReactNode;
|
||||
href?: string;
|
||||
disabled?: boolean;
|
||||
label: string;
|
||||
};
|
||||
|
||||
@@ -30,6 +32,9 @@ const useIconStyles = makeStyles({
|
||||
gridGap: 4,
|
||||
textAlign: 'center',
|
||||
},
|
||||
disabled: {
|
||||
color: 'gray',
|
||||
},
|
||||
label: {
|
||||
fontSize: '0.7rem',
|
||||
textTransform: 'uppercase',
|
||||
@@ -41,9 +46,24 @@ const useIconStyles = makeStyles({
|
||||
export function IconLinkVertical({
|
||||
icon = <LinkIcon />,
|
||||
href = '#',
|
||||
disabled = false,
|
||||
...props
|
||||
}: IconLinkVerticalProps) {
|
||||
const classes = useIconStyles();
|
||||
|
||||
if (disabled) {
|
||||
return (
|
||||
<Link
|
||||
className={classnames(classes.link, classes.disabled)}
|
||||
underline="none"
|
||||
{...props}
|
||||
>
|
||||
{icon}
|
||||
<span className={classes.label}>{props.label}</span>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link className={classes.link} href={href} {...props}>
|
||||
{icon}
|
||||
|
||||
@@ -26,9 +26,11 @@ export const addLinkClickListener = ({
|
||||
return dom => {
|
||||
Array.from(dom.getElementsByTagName('a')).forEach(elem => {
|
||||
elem.addEventListener('click', (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
const target = e.target as HTMLAnchorElement;
|
||||
if (target?.getAttribute('href')) {
|
||||
const href = target?.getAttribute('href');
|
||||
if (!href) return;
|
||||
if (!href.match(/^https?:\/\//i)) {
|
||||
e.preventDefault();
|
||||
onClick(e, target.getAttribute('href')!);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -27,6 +27,10 @@ export const rewriteDocLinks = (): Transformer => {
|
||||
.forEach((elem: T) => {
|
||||
const elemAttribute = elem.getAttribute(attributeName);
|
||||
if (elemAttribute) {
|
||||
// if link is external, add target to open in a new window or tab
|
||||
if (elemAttribute.match(/^https?:\/\//i)) {
|
||||
elem.setAttribute('target', '_blank');
|
||||
}
|
||||
const normalizedWindowLocation = window.location.href.endsWith('/')
|
||||
? window.location.href
|
||||
: `${window.location.href}/`;
|
||||
|
||||
@@ -3693,16 +3693,7 @@
|
||||
"@svgr/hast-util-to-babel-ast" "^5.4.0"
|
||||
svg-parser "^2.0.2"
|
||||
|
||||
"@svgr/plugin-svgo@4.3.x":
|
||||
version "4.3.1"
|
||||
resolved "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz#daac0a3d872e3f55935c6588dd370336865e9e32"
|
||||
integrity sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w==
|
||||
dependencies:
|
||||
cosmiconfig "^5.2.1"
|
||||
merge-deep "^3.0.2"
|
||||
svgo "^1.2.2"
|
||||
|
||||
"@svgr/plugin-svgo@^5.4.0":
|
||||
"@svgr/plugin-svgo@5.4.x", "@svgr/plugin-svgo@^5.4.0":
|
||||
version "5.4.0"
|
||||
resolved "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.4.0.tgz#45d9800b7099a6f7b4d85ebac89ab9abe8592f64"
|
||||
integrity sha512-3Cgv3aYi1l6SHyzArV9C36yo4kgwVdF3zPQUC6/aCDUeXAofDYwE5kk3e3oT5ZO2a0N3lB+lLGvipBG6lnG8EA==
|
||||
@@ -7863,7 +7854,7 @@ cosmiconfig@6.0.0, cosmiconfig@^6.0.0:
|
||||
path-type "^4.0.0"
|
||||
yaml "^1.7.2"
|
||||
|
||||
cosmiconfig@^5.0.0, cosmiconfig@^5.1.0, cosmiconfig@^5.2.1:
|
||||
cosmiconfig@^5.0.0, cosmiconfig@^5.1.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
|
||||
integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
|
||||
|
||||