diff --git a/docs-ui/package.json b/docs-ui/package.json
index 50bcae8d72..17c13f64f3 100644
--- a/docs-ui/package.json
+++ b/docs-ui/package.json
@@ -33,10 +33,11 @@
"prop-types": "^15.8.1",
"react": "19.1.1",
"react-dom": "19.1.1",
- "shiki": "^1.26.1",
+ "shiki": "^3.13.0",
"storybook": "^8.6.12"
},
"devDependencies": {
+ "@shikijs/transformers": "^3.13.0",
"@types/mdx": "^2.0.13",
"@types/node": "^20",
"@types/react": "19.1.9",
diff --git a/docs-ui/src/app/install/page.mdx b/docs-ui/src/app/install/page.mdx
index 329d477eca..cf14691441 100644
--- a/docs-ui/src/app/install/page.mdx
+++ b/docs-ui/src/app/install/page.mdx
@@ -1,33 +1,49 @@
import { CodeBlock } from '@/components/CodeBlock';
+import { Banner } from '@/components/Banner';
+import { snippet } from './snippets';
# How to install Backstage UI
-## 1. Import the package
+## How to import BUI's global styles
-Import the package using a package manager.
+Backstage UI works by importing a global CSS file at the root of your application. This file includes all the default styles for the components.
+First, you'll need to install the package using a package manager. For example, if you're using Yarn:
-
+
-## 2. Import the css files
+ );`}
+/>
-```tsx
-import '@backstage/ui/css/styles.css';
-```
+
-## 3. Start building ✨
+## How to use BUI components
-Now you can start building your plugin using the new design system.
+As a plugin maintainer, you can use BUI components in your plugin. As mentioned above, you should not import the styles
+again in your plugin as this will be handled at the root of your application. To get started, just add the library to
+your plugin and import the components you need.
-```tsx
-import { Flex, Button, Text } from '@backstage/ui';
+
-
- Hello World
- Click me
- ;
-```
+
## Next steps
diff --git a/docs-ui/src/app/install/snippets.ts b/docs-ui/src/app/install/snippets.ts
new file mode 100644
index 0000000000..7e63005172
--- /dev/null
+++ b/docs-ui/src/app/install/snippets.ts
@@ -0,0 +1,6 @@
+export const snippet = `import { Flex, Button, Text } from '@backstage/ui';
+
+
+ Hello World
+ Click me
+ ;`;
diff --git a/docs-ui/src/components/CodeBlock/client.tsx b/docs-ui/src/components/CodeBlock/client.tsx
index b4ee98f2f3..666d880358 100644
--- a/docs-ui/src/components/CodeBlock/client.tsx
+++ b/docs-ui/src/components/CodeBlock/client.tsx
@@ -1,10 +1,14 @@
'use client';
import { CodeBlockProps } from '.';
-import { Text } from '@backstage/ui';
import styles from './styles.module.css';
import parse from 'html-react-parser';
+// Convert markdown-style backticks to HTML code tags
+function parseMarkdownInlineCode(text: string): string {
+ return text.replace(/`([^`]+)`/g, '$1');
+}
+
export const CodeBlockClient = ({
out,
title,
@@ -16,7 +20,7 @@ export const CodeBlockClient = ({
{title && (
- {title}
+ {parse(parseMarkdownInlineCode(title))}
)}
{parse(out)}
diff --git a/docs-ui/src/components/CodeBlock/index.tsx b/docs-ui/src/components/CodeBlock/index.tsx
index 4c0fe72960..96fdb6bea5 100644
--- a/docs-ui/src/components/CodeBlock/index.tsx
+++ b/docs-ui/src/components/CodeBlock/index.tsx
@@ -1,4 +1,5 @@
import type { BundledLanguage } from 'shiki';
+import { transformerNotationDiff } from '@shikijs/transformers';
import { codeToHtml } from 'shiki';
import { CodeBlockClient } from './client';
@@ -15,6 +16,7 @@ export async function CodeBlock({ lang = 'tsx', title, code }: CodeBlockProps) {
light: 'min-light',
dark: 'min-dark',
},
+ transformers: [transformerNotationDiff({ matchAlgorithm: 'v3' })],
});
return
;
diff --git a/docs-ui/src/components/CodeBlock/styles.module.css b/docs-ui/src/components/CodeBlock/styles.module.css
index 767982a582..d786140482 100644
--- a/docs-ui/src/components/CodeBlock/styles.module.css
+++ b/docs-ui/src/components/CodeBlock/styles.module.css
@@ -16,8 +16,18 @@
.title {
border-bottom: 1px solid var(--border);
padding: 12px 20px;
- font-size: 0.875rem;
+ font-size: 0.8125rem;
+ color: var(--primary);
+ font-family: var(--font-regular);
+ font-weight: var(--font-weight-bold);
+}
+
+.title code {
+ background-color: var(--surface-1);
+ padding: 0.2rem 0.375rem;
+ border-radius: 0.25rem;
color: var(--secondary);
+ font-size: 0.8125rem;
}
.code {
diff --git a/docs-ui/src/css/globals.css b/docs-ui/src/css/globals.css
index f94dd74610..fa1a61eb4f 100644
--- a/docs-ui/src/css/globals.css
+++ b/docs-ui/src/css/globals.css
@@ -48,10 +48,11 @@ iframe {
.shiki,
.shiki span {
- background-color: transparent !important;
+ background-color: transparent;
font-family: var(--font-mono);
font-size: 0.875rem;
line-height: 1.7;
+ padding-block: 0.2rem;
}
[data-theme-mode='dark'] .shiki,
@@ -63,6 +64,36 @@ iframe {
text-decoration: var(--shiki-dark-text-decoration) !important;
}
+/* Add styles for diff notation */
+pre.shiki.has-diff .line.diff {
+ position: relative;
+ padding-left: 1.5rem;
+ border-radius: 0.25rem;
+}
+
+pre.shiki.has-diff .line.diff::before {
+ position: absolute;
+ left: 0.5rem;
+}
+
+pre.shiki.has-diff .line.diff.add {
+ background-color: rgba(46, 160, 67, 0.15);
+}
+
+pre.shiki.has-diff .line.diff.add::before {
+ content: '+';
+ color: #2ea043;
+}
+
+pre.shiki.has-diff .line.diff.remove {
+ background-color: rgba(248, 81, 73, 0.15);
+}
+
+pre.shiki.has-diff .line.diff.remove::before {
+ content: '-';
+ color: #f85149;
+}
+
.cm-editor {
transition: background-color 0.2s ease-in-out;
}
diff --git a/docs-ui/yarn.lock b/docs-ui/yarn.lock
index 0969bf0ffa..538b4947b2 100644
--- a/docs-ui/yarn.lock
+++ b/docs-ui/yarn.lock
@@ -949,70 +949,78 @@ __metadata:
languageName: node
linkType: hard
-"@shikijs/core@npm:1.29.2":
- version: 1.29.2
- resolution: "@shikijs/core@npm:1.29.2"
+"@shikijs/core@npm:3.13.0":
+ version: 3.13.0
+ resolution: "@shikijs/core@npm:3.13.0"
dependencies:
- "@shikijs/engine-javascript": "npm:1.29.2"
- "@shikijs/engine-oniguruma": "npm:1.29.2"
- "@shikijs/types": "npm:1.29.2"
- "@shikijs/vscode-textmate": "npm:^10.0.1"
+ "@shikijs/types": "npm:3.13.0"
+ "@shikijs/vscode-textmate": "npm:^10.0.2"
"@types/hast": "npm:^3.0.4"
- hast-util-to-html: "npm:^9.0.4"
- checksum: 10/83dc5e86efc587d513268175ff43e8273567d2c6616d725bff15b08cf243d90f9371d6fa76ba49bb0e9823fc9947c8d8c650c81cfb19c3eb726178326f639a55
+ hast-util-to-html: "npm:^9.0.5"
+ checksum: 10/c9b301a170cd76fa2ce446adee26b539b19204107a2e60207f3f5e7d96773df322367f6035e2d689d43f97a3e9f741793e976c366015d8e3a9709dcac1399af2
languageName: node
linkType: hard
-"@shikijs/engine-javascript@npm:1.29.2":
- version: 1.29.2
- resolution: "@shikijs/engine-javascript@npm:1.29.2"
+"@shikijs/engine-javascript@npm:3.13.0":
+ version: 3.13.0
+ resolution: "@shikijs/engine-javascript@npm:3.13.0"
dependencies:
- "@shikijs/types": "npm:1.29.2"
- "@shikijs/vscode-textmate": "npm:^10.0.1"
- oniguruma-to-es: "npm:^2.2.0"
- checksum: 10/b49461ff7152650ffdbd77332d1c70e24a2ff1abe869e1038694b410194c6403fe5e8fce104fdd305d10c18702a50c1edbdb87172aa09f11340bc1203ed38488
+ "@shikijs/types": "npm:3.13.0"
+ "@shikijs/vscode-textmate": "npm:^10.0.2"
+ oniguruma-to-es: "npm:^4.3.3"
+ checksum: 10/acd4e78fdc732738c6a3a9f254011b7d8995a2149f2f72f7396d5e4514f3b0c3fdc767d52bf8852d65066e613dd8d1157bc4900442ab42684db7ef7396a44871
languageName: node
linkType: hard
-"@shikijs/engine-oniguruma@npm:1.29.2":
- version: 1.29.2
- resolution: "@shikijs/engine-oniguruma@npm:1.29.2"
+"@shikijs/engine-oniguruma@npm:3.13.0":
+ version: 3.13.0
+ resolution: "@shikijs/engine-oniguruma@npm:3.13.0"
dependencies:
- "@shikijs/types": "npm:1.29.2"
- "@shikijs/vscode-textmate": "npm:^10.0.1"
- checksum: 10/bb3e2c01da84d573251ebc289b1ecf815261024dea5bddb93ad56c3504a71cde3630db070be401ed3bbcd23a8a839ec78984a82317f9c9d0bba58daed935b781
+ "@shikijs/types": "npm:3.13.0"
+ "@shikijs/vscode-textmate": "npm:^10.0.2"
+ checksum: 10/bc7f1c69640ccece9a3ac3f3adc9cebde9c24bcd722747cc464c338a32725af2b9087a42646cd0f56fbea98d99414918c558f2ca0beadc13db0a740183e7707f
languageName: node
linkType: hard
-"@shikijs/langs@npm:1.29.2":
- version: 1.29.2
- resolution: "@shikijs/langs@npm:1.29.2"
+"@shikijs/langs@npm:3.13.0":
+ version: 3.13.0
+ resolution: "@shikijs/langs@npm:3.13.0"
dependencies:
- "@shikijs/types": "npm:1.29.2"
- checksum: 10/01f62d31c653c718a992918357e54d2d312c8da407997565fc19056fbf47f0fadc0f9f4b5fe1e1ba7b7d08e3984fb1f962159503ef0edd81fab5ee8bfdbf9080
+ "@shikijs/types": "npm:3.13.0"
+ checksum: 10/2a0478246ce61745d9012cf5051c9790ef5afad6c89fe5716be4a81d04d7dfd9ffc90af0bad0be0061111bfc001a3bc0c55ffd4fc0b82bc1c09a4c33d7b593ca
languageName: node
linkType: hard
-"@shikijs/themes@npm:1.29.2":
- version: 1.29.2
- resolution: "@shikijs/themes@npm:1.29.2"
+"@shikijs/themes@npm:3.13.0":
+ version: 3.13.0
+ resolution: "@shikijs/themes@npm:3.13.0"
dependencies:
- "@shikijs/types": "npm:1.29.2"
- checksum: 10/b81606dd882136e3fd751d0829133b5e66b10b8e32bd52ce16e7eac8755891c23e43f3ce06e65b97a75d2bc3b17e7fdb9115e9812679bb820ab163915868fd8b
+ "@shikijs/types": "npm:3.13.0"
+ checksum: 10/4ab0ecf1ddb35e387cef22e267cdf3ed7548a84f24ad58885d19401f75cc01a5a10152ee0196222e01cead8202f20012615aa0076f798599f7dfc2bb7beaa617
languageName: node
linkType: hard
-"@shikijs/types@npm:1.29.2":
- version: 1.29.2
- resolution: "@shikijs/types@npm:1.29.2"
+"@shikijs/transformers@npm:^3.13.0":
+ version: 3.13.0
+ resolution: "@shikijs/transformers@npm:3.13.0"
dependencies:
- "@shikijs/vscode-textmate": "npm:^10.0.1"
+ "@shikijs/core": "npm:3.13.0"
+ "@shikijs/types": "npm:3.13.0"
+ checksum: 10/30f3e66334b60320dc976b9f645f823ba13b312aead4c891ae6db23d076f1570dad488443f603fb5eecd5937973ba7c2907da6678ccae2363a66e0c5b173bb02
+ languageName: node
+ linkType: hard
+
+"@shikijs/types@npm:3.13.0":
+ version: 3.13.0
+ resolution: "@shikijs/types@npm:3.13.0"
+ dependencies:
+ "@shikijs/vscode-textmate": "npm:^10.0.2"
"@types/hast": "npm:^3.0.4"
- checksum: 10/579e64b6e8cb83023232b8060b08f51cff3909b199d0d1a0c58ed500c898dd34b74bf0457336fa2e6bee1005889e198d7d924347ad616eee30c6ae4c89a67ab8
+ checksum: 10/a57cc95847edd84134166de1f11a044e356581834b2dfd75dcd67f2221aef6f20f505839c090a76b7c8e0a79d7d5cee829de50d261f363a633ae9afca29546c4
languageName: node
linkType: hard
-"@shikijs/vscode-textmate@npm:^10.0.1":
+"@shikijs/vscode-textmate@npm:^10.0.2":
version: 10.0.2
resolution: "@shikijs/vscode-textmate@npm:10.0.2"
checksum: 10/d924cba8a01cd9ca12f56ba097d628fdb81455abb85884c8d8a5ae85b628a37dd5907e7691019b97107bd6608c866adf91ba04a1c3bba391281c88e386c044ea
@@ -2330,6 +2338,7 @@ __metadata:
"@mdx-js/react": "npm:^3.1.0"
"@next/mdx": "npm:15.3.4"
"@remixicon/react": "npm:^4.6.0"
+ "@shikijs/transformers": "npm:^3.13.0"
"@storybook/react": "npm:^8.6.12"
"@types/mdx": "npm:^2.0.13"
"@types/node": "npm:^20"
@@ -2349,7 +2358,7 @@ __metadata:
prop-types: "npm:^15.8.1"
react: "npm:19.1.1"
react-dom: "npm:19.1.1"
- shiki: "npm:^1.26.1"
+ shiki: "npm:^3.13.0"
storybook: "npm:^8.6.12"
typescript: "npm:^5"
languageName: unknown
@@ -2429,13 +2438,6 @@ __metadata:
languageName: node
linkType: hard
-"emoji-regex-xs@npm:^1.0.0":
- version: 1.0.0
- resolution: "emoji-regex-xs@npm:1.0.0"
- checksum: 10/e216ec4270f765e1097cefc1b9518a7166b872b4424c60a85d79765f318d989cd458e036c76c13e9ce2ed1fe1bb5935a7fd5c1fab7600668bc8e92a789045b3c
- languageName: node
- linkType: hard
-
"emoji-regex@npm:^8.0.0":
version: 8.0.0
resolution: "emoji-regex@npm:8.0.0"
@@ -3577,7 +3579,7 @@ __metadata:
languageName: node
linkType: hard
-"hast-util-to-html@npm:^9.0.4":
+"hast-util-to-html@npm:^9.0.5":
version: 9.0.5
resolution: "hast-util-to-html@npm:9.0.5"
dependencies:
@@ -5351,14 +5353,21 @@ __metadata:
languageName: node
linkType: hard
-"oniguruma-to-es@npm:^2.2.0":
- version: 2.3.0
- resolution: "oniguruma-to-es@npm:2.3.0"
+"oniguruma-parser@npm:^0.12.1":
+ version: 0.12.1
+ resolution: "oniguruma-parser@npm:0.12.1"
+ checksum: 10/2e7e308ec222f377b4be21e87f009729ce1cc014511d35a50440e7270a17413e4859b8c7ad1985123abe1089bda5ad2d0feccc75f7de25d9cb272b7cc34b4f3c
+ languageName: node
+ linkType: hard
+
+"oniguruma-to-es@npm:^4.3.3":
+ version: 4.3.3
+ resolution: "oniguruma-to-es@npm:4.3.3"
dependencies:
- emoji-regex-xs: "npm:^1.0.0"
- regex: "npm:^5.1.1"
- regex-recursion: "npm:^5.1.1"
- checksum: 10/7ac89fe04791650c21a146e58c985de394597e0ab3eb7d7c46699d09f87d6aca63d9f2470f1473c5adfa16961c360df6858e6a24b2429ebd7c73620ca68aec98
+ oniguruma-parser: "npm:^0.12.1"
+ regex: "npm:^6.0.1"
+ regex-recursion: "npm:^6.0.2"
+ checksum: 10/49b372569d335077c32bda066ac1da4a3f15dd25b717025cf43417fabd71d56e1152debcd8a832596e180d721b808822c88e65eb12abb26665ab8fe017f3c861
languageName: node
linkType: hard
@@ -5714,13 +5723,12 @@ __metadata:
languageName: node
linkType: hard
-"regex-recursion@npm:^5.1.1":
- version: 5.1.1
- resolution: "regex-recursion@npm:5.1.1"
+"regex-recursion@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "regex-recursion@npm:6.0.2"
dependencies:
- regex: "npm:^5.1.1"
regex-utilities: "npm:^2.3.0"
- checksum: 10/9ec7e677743e00c14c3d5c63de1d15e5126a69c58da43e60b2c49abf940981f0269442c919e03f66d6837d0ac55ccf7981581e9d1be2a332a968c016edee226e
+ checksum: 10/ce25d54bdf79e38ae663c26a7f265754047b918e8b771b4ed3c871e9a926b85b195dcd0dd7a6444c82d2c9db9b2cbcaf51a353a807b469a3ad7a2172f27f21d4
languageName: node
linkType: hard
@@ -5731,12 +5739,12 @@ __metadata:
languageName: node
linkType: hard
-"regex@npm:^5.1.1":
- version: 5.1.1
- resolution: "regex@npm:5.1.1"
+"regex@npm:^6.0.1":
+ version: 6.0.1
+ resolution: "regex@npm:6.0.1"
dependencies:
regex-utilities: "npm:^2.3.0"
- checksum: 10/956d0f34afa8086551dc9a0e2c575cb6d7ed5122d6d440a72cfbcd1f9adb5a3dcce4dcb61ec69eaecfcbc508cfd25075ac60d011bab5f28f1b2a36220e09a245
+ checksum: 10/8f8c35ce0a74b65ce29495b8c18767a4b2724ca4a4b4acfc4d45a2851a5afdbc4daae447a1a762f8faf06a1efe3d7dd8cfc4ebbee9f7c55411d4bd30f6976026
languageName: node
linkType: hard
@@ -6142,19 +6150,19 @@ __metadata:
languageName: node
linkType: hard
-"shiki@npm:^1.26.1":
- version: 1.29.2
- resolution: "shiki@npm:1.29.2"
+"shiki@npm:^3.13.0":
+ version: 3.13.0
+ resolution: "shiki@npm:3.13.0"
dependencies:
- "@shikijs/core": "npm:1.29.2"
- "@shikijs/engine-javascript": "npm:1.29.2"
- "@shikijs/engine-oniguruma": "npm:1.29.2"
- "@shikijs/langs": "npm:1.29.2"
- "@shikijs/themes": "npm:1.29.2"
- "@shikijs/types": "npm:1.29.2"
- "@shikijs/vscode-textmate": "npm:^10.0.1"
+ "@shikijs/core": "npm:3.13.0"
+ "@shikijs/engine-javascript": "npm:3.13.0"
+ "@shikijs/engine-oniguruma": "npm:3.13.0"
+ "@shikijs/langs": "npm:3.13.0"
+ "@shikijs/themes": "npm:3.13.0"
+ "@shikijs/types": "npm:3.13.0"
+ "@shikijs/vscode-textmate": "npm:^10.0.2"
"@types/hast": "npm:^3.0.4"
- checksum: 10/93de1ebc768ff497ba36720f3b385bff65a853248fdfc0afcb2aea81a43560b1bdc7db9e8417df11a87e106b0de0943989c6301daf62a43d09bd9ac7bc776bf3
+ checksum: 10/8d7cd039ac8df548f724047b4ba81cd84c09e8b96f411eb7c781d3d105c96ff2ec6f64e1bac724fd6fc56ac2926322bc2466124ea279d04c5ef668d5a04219bb
languageName: node
linkType: hard