Merge branch 'master' of github.com:kurtaking/backstage into patch-4

This commit is contained in:
Kurt King
2025-11-17 10:27:27 -07:00
256 changed files with 5199 additions and 2258 deletions
+14
View File
@@ -0,0 +1,14 @@
---
'@backstage/ui': minor
---
**BREAKING**: Removed central `componentDefinitions` object and related type utilities (`ComponentDefinitionName`, `ComponentClassNames`).
Component definitions are primarily intended for documenting the CSS class API for theming purposes, not for programmatic use in JavaScript/TypeScript.
**Migration Guide:**
If you were using component definitions or class names to build custom components, we recommend migrating to either:
- Use Backstage UI components directly as building blocks, or
- Duplicate the component CSS in your own stylesheets instead of relying on internal class names
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
Fixed responsiveness issues with catalog entity content layout using the new frontend system.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-plugin-api': minor
---
Renamed `ExtensionDefinition` to `OverridableExtensionDefinition` and introduced a slimmer `ExtensionDefinition` type that does not include override methods. The overridable type is generally used as an output type, while plain `ExtensionDefinition`s are used for input. This reduces type conflicts across different of `@backstage/frontend-plugin-api`, improving long-term compatibility.
+1 -1
View File
@@ -1,5 +1,5 @@
{
"mode": "pre",
"mode": "exit",
"tag": "next",
"initialVersions": {
"example-app": "0.2.114",
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
Fixed missing margins for entity warning content area on catalog entity page in NFS.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-notifications-backend-module-slack': patch
---
When an error message is logged due to inability to send a message with the Slack SDK, include the Slack Channel ID in the message to aid debugging.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-import': patch
---
Fixed missing `catalog.entity.create` permission authorization in the default page extension.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
Fixed catalog filter "all" not appearing as selected when set as the initially selected filter.
@@ -23,7 +23,7 @@ jobs:
comment-cache-key: ${{ steps.hash.outputs.COMMENT_FILE_HASH }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
disable-sudo: true
egress-policy: block
@@ -32,7 +32,7 @@ jobs:
- name: 'Download artifacts'
# Fetch output (zip archive) from the workflow run that triggered this workflow.
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
@@ -74,7 +74,7 @@ jobs:
- name: Cache Comment
if: ${{ steps.event.outputs.ACTION != 'closed' }}
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: comment.md
key: ${{ steps.hash.outputs.COMMENT_FILE_HASH }}
+2 -2
View File
@@ -14,11 +14,11 @@ jobs:
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
# Fetch the commit that's merged into the base rather than the target ref
# This will let us diff only the contents of the PR, without fetching more history
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -23,11 +23,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
# Fetch the commit that's merged into the base rather than the target ref
# This will let us diff only the contents of the PR, without fetching more history
+3 -3
View File
@@ -24,11 +24,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
ref: '${{ github.event.pull_request.merge_commit_sha }}'
@@ -44,7 +44,7 @@ jobs:
node generate.js ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} > message.txt
- name: Post Message
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
env:
ISSUE_NUMBER: ${{ github.event.pull_request.number }}
with:
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
name: Test ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+5 -5
View File
@@ -28,11 +28,11 @@ jobs:
name: Install ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: use node.js ${{ matrix.node-version }}
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
@@ -64,11 +64,11 @@ jobs:
name: Verify ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: use node.js ${{ matrix.node-version }}
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
@@ -210,7 +210,7 @@ jobs:
INTEGRATION_TEST_AZURE_TOKEN: ${{ secrets.INTEGRATION_TEST_AZURE_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: fetch master branch
run: git fetch origin master
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+2 -2
View File
@@ -20,12 +20,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
path: backstage
ref: ${{ github.event.client_payload.version && env.RELEASE_VERSION || github.ref }}
+7 -7
View File
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -54,7 +54,7 @@ jobs:
result-encoding: string
- name: checkout latest release
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
ref: refs/tags/${{ steps.find-release.outputs.result }}
@@ -135,12 +135,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: checkout master
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Use Node.js 20.x
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
@@ -240,7 +240,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -252,7 +252,7 @@ jobs:
# Stable docs
- name: checkout latest release
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
ref: refs/tags/${{ needs.stable.outputs.release }}
@@ -286,7 +286,7 @@ jobs:
# Next docs
- name: checkout master
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
clean: false
+2 -2
View File
@@ -68,7 +68,7 @@ jobs:
INTEGRATION_TEST_AZURE_TOKEN: ${{ secrets.INTEGRATION_TEST_AZURE_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: use node.js ${{ matrix.node-version }}
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
@@ -151,7 +151,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
if: github.repository == 'backstage/backstage'
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -20,7 +20,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+2 -2
View File
@@ -17,13 +17,13 @@ jobs:
steps:
# Inspired by https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Read PR Number
id: pr-number
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request )
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+2 -2
View File
@@ -29,12 +29,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: 'Checkout code'
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
persist-credentials: false
+3 -3
View File
@@ -8,12 +8,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Use Node.js 20.x
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
@@ -27,7 +27,7 @@ jobs:
cache-prefix: ${{ runner.os }}-v20.x
- name: Checkout backstage/docs-ui
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
repository: backstage/docs-ui
path: bui-external-docs
+2 -2
View File
@@ -10,11 +10,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
# Fetch changes to previous commit - required for 'only_changed' in Prettier action
fetch-depth: 0
@@ -11,12 +11,12 @@ jobs:
if: github.actor == 'dependabot[bot]' && github.repository == 'backstage/backstage'
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 2
ref: ${{ github.head_ref }}
@@ -26,7 +26,7 @@ jobs:
git config --global user.email noreply@backstage.io
git config --global user.name 'Github changeset workflow'
- name: Generate changeset
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
script: |
const { promises: fs } = require('fs');
+4 -4
View File
@@ -8,12 +8,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
# 'v' prefix is added here for the tag, we keep it out of the manifest logic
ref: v${{ github.event.client_payload.version }}
@@ -35,7 +35,7 @@ jobs:
# Checkout backstage/versions into /backstage/versions, which is where store the output
- name: Checkout versions
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
repository: backstage/versions
path: versions
@@ -71,7 +71,7 @@ jobs:
git push
- name: Dispatch update-helper update
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
# TODO(Rugvip): Remove the create-app dispatch once we've been on the release version for a while
@@ -11,12 +11,12 @@ jobs:
if: github.actor == 'renovate[bot]' && github.repository == 'backstage/backstage'
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 2
ref: ${{ github.head_ref }}
@@ -26,7 +26,7 @@ jobs:
git config --global user.email noreply@backstage.io
git config --global user.name 'Github changeset workflow'
- name: Generate changeset
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with:
script: |
const { promises: fs } = require("fs");
@@ -12,11 +12,11 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Use Node.js 20.x
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
+2 -2
View File
@@ -25,11 +25,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Monitor and Synchronize Snyk Policies
uses: snyk/actions/node@9adf32b1121593767fc3c057af55b55db032dc04 # master
with:
+2 -2
View File
@@ -14,11 +14,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 20000
fetch-tags: true
@@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+2 -2
View File
@@ -20,11 +20,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Use Node.js 20.x
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
name: Chromatic
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+2 -2
View File
@@ -24,12 +24,12 @@ jobs:
name: Chromatic
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 10000 # Required to retrieve git history
+2 -2
View File
@@ -42,12 +42,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
+2 -2
View File
@@ -12,11 +12,11 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
# Vale does not support file excludes, so we use the script to generate a list of files instead
# The action also does not allow args or a local config file to be passed in, so the files array
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
name: E2E Linux ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+2 -2
View File
@@ -43,11 +43,11 @@ jobs:
name: E2E Linux ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Configure Git
run: |
+2 -2
View File
@@ -32,11 +32,11 @@ jobs:
name: Techdocs
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.9'
@@ -25,7 +25,7 @@ jobs:
name: E2E Windows ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+2 -2
View File
@@ -33,7 +33,7 @@ jobs:
name: E2E Windows ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -44,7 +44,7 @@ jobs:
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Configure Git
run: |
+2 -2
View File
@@ -14,12 +14,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Install Fossa
run: "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | bash"
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
name: Microsite
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+7 -7
View File
@@ -28,7 +28,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -59,7 +59,7 @@ jobs:
result-encoding: string
- name: checkout latest release
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
ref: refs/tags/${{ steps.find-release.outputs.result }}
@@ -137,12 +137,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: checkout master
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Use Node.js 20.x
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
@@ -234,11 +234,11 @@ jobs:
name: Microsite
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Use Node.js 20.x
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
@@ -295,7 +295,7 @@ jobs:
run: yarn build:api-docs
- name: checkout master
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
clean: false
@@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -15,11 +15,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Use Node.js 20.x
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
+2 -2
View File
@@ -29,11 +29,11 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: use node.js ${{ matrix.node-version }}
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
+25
View File
@@ -13,3 +13,28 @@ yarn start
## Deployment
Deployments are done automatically when a PR is merged into the `master` branch. We host the website using Github pages.
## Maintaining Component Changelogs
After a `@backstage/ui` release, sync the component changelogs to keep documentation up-to-date:
```bash
yarn sync:changelog
```
This script:
- Parses `packages/ui/CHANGELOG.md` for new versions
- Extracts entries tagged with "Affected components: ..."
- Updates `src/utils/changelog.ts` with new entries
- Handles both component-specific and general package changes
After running, review the changes in `src/utils/changelog.ts` and commit them.
**Preview changes before writing:**
```bash
yarn sync:changelog:dry-run
```
Running this gives you a summary of what would be written, without actually adding or changing any files.
+5 -1
View File
@@ -8,6 +8,8 @@
"lint": "next lint",
"prestart": "yarn sync:css",
"start": "next dev",
"sync:changelog": "node scripts/sync-changelog.mjs",
"sync:changelog:dry-run": "node scripts/sync-changelog.mjs --dry-run",
"sync:css": "node scripts/sync-css.js",
"sync:css:watch": "node scripts/sync-css.js --watch"
},
@@ -39,6 +41,7 @@
"storybook": "^8.6.12"
},
"devDependencies": {
"@octokit/rest": "^22.0.1",
"@shikijs/transformers": "^3.13.0",
"@types/mdx": "^2.0.13",
"@types/node": "^20",
@@ -48,6 +51,7 @@
"eslint": "^8",
"eslint-config-next": "15.3.4",
"lightningcss": "^1.28.2",
"typescript": "^5"
"typescript": "^5",
"unified": "^11.0.4"
}
}
+991
View File
@@ -0,0 +1,991 @@
#!/usr/bin/env node
/* eslint-disable no-restricted-syntax */
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import { Octokit } from '@octokit/rest';
import { execSync } from 'child_process';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/**
* Compare two semantic versions.
* Returns: 1 if versionA > versionB, -1 if versionA < versionB, 0 if equal
* Handles pre-release versions (e.g., "0.9.0-next.2")
*/
function compareVersions(versionA, versionB) {
// Strip 'v' prefix if present
versionA = versionA.replace(/^v/, '');
versionB = versionB.replace(/^v/, '');
// Split into [major.minor.patch, prerelease]
const [versionABase, versionAPre] = versionA.split('-');
const [versionBBase, versionBPre] = versionB.split('-');
// Compare base versions
const versionAParts = versionABase.split('.').map(Number);
const versionBParts = versionBBase.split('.').map(Number);
for (
let i = 0;
i < Math.max(versionAParts.length, versionBParts.length);
i++
) {
const versionAPart = versionAParts[i] || 0;
const versionBPart = versionBParts[i] || 0;
if (versionAPart > versionBPart) return 1;
if (versionAPart < versionBPart) return -1;
}
// If base versions equal, compare pre-release
if (!versionAPre && !versionBPre) return 0;
if (!versionAPre) return 1; // versionA is release, versionB is pre-release
if (!versionBPre) return -1; // versionA is pre-release, versionB is release
// Both have pre-release, compare them
return versionAPre.localeCompare(versionBPre);
}
/**
* Check if versionA is newer than versionB
*/
function isNewerVersion(versionA, versionB) {
return compareVersions(versionA, versionB) > 0;
}
/**
* Normalize version to base version (remove pre-release suffix)
* "0.9.0-next.3" → "0.9.0"
* "0.9.0" → "0.9.0"
*/
function normalizeVersion(version) {
return version.split('-')[0];
}
/**
* Read the existing changelog.ts and find the highest version number
* by scanning the changelogs/ directory for version files
*/
function getLastSyncedVersion(changelogPath) {
try {
// Scan changelogs/ directory for latest version file
const changelogsDir = path.join(path.dirname(changelogPath), 'changelogs');
if (!fs.existsSync(changelogsDir)) {
return null;
}
// Read all version files (v0.1.0.ts, v0.2.0.ts, etc.)
const files = fs
.readdirSync(changelogsDir)
.filter(f => f.match(/^v\d+\.\d+\.\d+\.ts$/))
.map(f => f.replace(/^v/, '').replace(/\.ts$/, ''));
if (files.length === 0) {
return null;
}
// Find highest version
let highest = files[0];
for (const version of files) {
if (compareVersions(version, highest) > 0) {
highest = version;
}
}
return highest;
} catch (error) {
console.error(`Error reading changelog file: ${error.message}`);
return null;
}
}
/**
* Convert PascalCase component name to kebab-case slug
* Avatar -> avatar
* ButtonIcon -> button-icon
* SearchField -> searchfield (special case per existing data)
*/
function pascalToKebab(str) {
// Special cases observed in changelog.ts
const specialCases = {
SearchField: 'searchfield',
TextField: 'textfield',
DataTable: 'datatable',
ScrollArea: 'scrollarea',
};
if (specialCases[str]) {
return specialCases[str];
}
// General conversion: insert hyphen before uppercase letters
return str
.replace(/([A-Z])/g, '-$1')
.toLowerCase()
.replace(/^-/, ''); // Remove leading hyphen
}
/**
* Map component name to valid Component type slug
* Returns null if component not recognized
*/
function mapComponentName(name, validComponents) {
const kebab = pascalToKebab(name.trim());
const kebabLower = kebab.toLowerCase();
// Check if it's a valid component
const valid = validComponents.find(c => c.toLowerCase() === kebabLower);
return valid || null;
}
/**
* Get valid component names from types.ts Component type
*/
function getValidComponents(changelogPath) {
// Read from types.ts instead of changelog.ts
const typesPath = changelogPath.replace('changelog.ts', 'types.ts');
const content = fs.readFileSync(typesPath, 'utf-8');
// Extract Component type union
const typeMatch = content.match(/export type Component =([^;]+);/s);
if (!typeMatch) {
throw new Error('Could not find Component type definition');
}
// Extract string literals from the union
const components = typeMatch[1]
.match(/['"]([^'"]+)['"]/g)
.map(s => s.replace(/['"]/g, ''));
return components;
}
/**
* Parse CHANGELOG.md and extract entries newer than sinceVersion
*/
async function parseChangelogMd(changelogPath, sinceVersion, validComponents) {
const content = fs.readFileSync(changelogPath, 'utf-8');
const tree = unified().use(remarkParse).parse(content);
const entries = [];
let currentVersion = null;
let currentSection = null; // 'Minor Changes', 'Patch Changes', 'Major Changes'
let processedCount = 0;
// Walk through the markdown AST
async function walk(node, depth = 0) {
// Version headers (## 0.9.0)
if (node.type === 'heading' && node.depth === 2) {
const versionText = extractText(node).trim();
// Validate that this is actually a version number (X.Y.Z or X.Y.Z-pre.N)
// Skip headings that are just markdown content within changelog entries
if (/^\d+\.\d+\.\d+/.test(versionText)) {
currentVersion = versionText;
currentSection = null;
}
return;
}
// Section headers (### Minor Changes)
if (node.type === 'heading' && node.depth === 3) {
const sectionText = extractText(node);
currentSection = sectionText.trim();
return;
}
// List items (- 539cf26: description)
if (node.type === 'listItem' && currentVersion && currentSection) {
// Only process if version is newer than sinceVersion
if (!sinceVersion || isNewerVersion(currentVersion, sinceVersion)) {
const entry = await parseListItem(
node,
currentVersion,
currentSection,
validComponents,
content,
);
if (entry) {
entries.push(entry);
processedCount++;
// Progress logging every 50 entries
if (processedCount % 50 === 0) {
process.stdout.write(`\r Processed ${processedCount} entries...`);
}
}
}
}
// Recurse into children
if (node.children) {
for (const child of node.children) {
await walk(child, depth + 1);
}
}
}
await walk(tree);
// Clear progress line
if (processedCount > 0) {
process.stdout.write(`\r Processed ${processedCount} entries - done!\n`);
}
return entries;
}
/**
* Extract plain text from a markdown node
*/
function extractText(node) {
if (node.type === 'text') {
return node.value;
}
if (node.children) {
return node.children.map(extractText).join('');
}
return '';
}
/**
* Extract raw markdown content from a node using position offsets
* This preserves all formatting: code blocks, lists, bold/italic, etc.
*/
function extractMarkdown(node, sourceText) {
if (!node.position) {
return extractText(node); // Fallback to text extraction
}
const start = node.position.start.offset;
const end = node.position.end.offset;
if (start === undefined || end === undefined) {
return extractText(node);
}
return sourceText.slice(start, end).trim();
}
/**
* Parse a list item to extract changelog entry
* NOTE: PR numbers are NOT fetched here - they're fetched later only for new entries
*/
async function parseListItem(
node,
version,
section,
validComponents,
sourceText,
) {
// Extract the full text content for SHA parsing
const fullText = extractText(node);
// Parse commit SHA and description
// Format: "- 539cf26: description..."
const match = fullText.match(/^-?\s*([a-f0-9]+):\s*(.+)/s);
if (!match) {
return null;
}
const commitSha = match[1];
// Extract full markdown content from the list item
let fullMarkdown = extractMarkdown(node, sourceText);
// Remove the commit SHA prefix from markdown
let description = fullMarkdown.replace(/^-?\s*[a-f0-9]+:\s*/, '').trim();
// Auto-detect components from "Affected components:" line
let components = [];
const componentMatch = description.match(/Affected components?:\s*([^\n]+)/i);
if (componentMatch) {
const componentNames = componentMatch[1]
.split(',')
.map(name => name.trim())
.filter(Boolean);
components = componentNames
.map(name => mapComponentName(name, validComponents))
.filter(Boolean);
// Optionally strip "Affected components:" line from description
description = description
.replace(/\n*Affected components?:[ \t]*[^\n]+/i, '')
.trim();
}
const prs = []; // Will be populated later by fetchPRNumbers()
// Infer type from section and description
const type = inferChangeType(section, description, version);
return {
version: normalizeVersion(version),
section,
commitSha,
description,
components,
prs,
type,
};
}
/**
* Infer change type from section and description
*/
function inferChangeType(section, description, version) {
const isPre1 = version.startsWith('0.');
// Check description keywords first
if (description.match(/^(New|Add(ed)?)\s/i)) {
return 'new';
}
if (description.includes('BREAKING')) {
return 'breaking';
}
// Infer from section
if (section === 'Minor Changes') {
return isPre1 ? 'breaking' : undefined;
} else if (section === 'Major Changes') {
return 'breaking';
} else if (section === 'Patch Changes') {
return 'fix';
}
return undefined;
}
/**
* Generate new changelog entries and update changelog.ts
*/
/**
* Fetch PR numbers for entries that need them
* Only fetches for entries with empty prs array (new entries)
*/
async function fetchPRNumbers(entries, dryRun = false) {
const entriesNeedingPRs = entries.filter(
e => e.prs.length === 0 && e.commitSha,
);
if (entriesNeedingPRs.length === 0) {
return;
}
console.log(
`\n🔍 Fetching PR numbers for ${entriesNeedingPRs.length} new entries...`,
);
let fetchedCount = 0;
const startTime = Date.now();
for (const entry of entriesNeedingPRs) {
const prNumber = await findPRNumber(entry.commitSha);
if (prNumber) {
entry.prs.push(prNumber);
}
fetchedCount++;
// Progress every 10 lookups
if (fetchedCount % 10 === 0 || fetchedCount === entriesNeedingPRs.length) {
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
const rate = ((fetchedCount / (Date.now() - startTime)) * 1000).toFixed(
1,
);
process.stdout.write(
`\r Fetched ${fetchedCount}/${entriesNeedingPRs.length} PR numbers (${elapsed}s, ~${rate} req/s)`,
);
}
}
const totalTime = ((Date.now() - startTime) / 1000).toFixed(1);
const foundCount = entriesNeedingPRs.filter(e => e.prs.length > 0).length;
console.log(
`\n ✓ Found ${foundCount}/${entriesNeedingPRs.length} PR numbers in ${totalTime}s`,
);
}
/**
* Generate per-version changelog files in changelogs/ directory
*/
async function generateVersionFiles(entries, changelogsDir, dryRun = false) {
// Group entries by normalized version
const byVersion = {};
entries.forEach(entry => {
const version = entry.version;
if (!byVersion[version]) {
byVersion[version] = [];
}
byVersion[version].push(entry);
});
const versionFiles = [];
const skippedVersions = [];
const generatedVersions = [];
for (const [version, versionEntries] of Object.entries(byVersion)) {
const fileName = `v${version}.ts`;
const filePath = path.join(changelogsDir, fileName);
const varName = `changelog_${version.replace(/\./g, '_')}`;
// Check if file already exists - skip if it does
if (fs.existsSync(filePath)) {
skippedVersions.push(version);
// Still add to versionFiles array so main changelog.ts can import it
versionFiles.push({
version,
fileName,
filePath,
varName,
content: null, // No content needed for existing files
skipped: true,
});
continue;
}
// Generate TypeScript code for this version
const entryObjects = versionEntries
.map(entry => {
const componentsStr = `[${entry.components
.map(c => `'${c}'`)
.join(', ')}]`;
const prsStr = `[${entry.prs.map(pr => `'${pr}'`).join(', ')}]`;
const typeStr = entry.type ? `type: '${entry.type}',` : '';
const shaStr = entry.commitSha
? `commitSha: '${entry.commitSha}',`
: '';
// Escape description for template literal
const descEscaped = entry.description
.replace(/\\/g, '\\\\')
.replace(/`/g, '\\`')
.replace(/\${/g, '\\${');
return ` {
components: ${componentsStr},
version: '${entry.version}',
prs: ${prsStr},
description: \`${descEscaped}\`,
${typeStr}
${shaStr}
}`;
})
.join(',\n');
const fileContent = `import type { ChangelogProps } from '../types';
export const ${varName}: ChangelogProps[] = [
${entryObjects}
];
`;
generatedVersions.push(version);
versionFiles.push({
version,
fileName,
filePath,
varName,
content: fileContent,
skipped: false,
});
if (!dryRun) {
fs.writeFileSync(filePath, fileContent, 'utf-8');
}
}
// Log summary
if (skippedVersions.length > 0) {
console.log(
`\n⏭️ Skipped ${
skippedVersions.length
} existing version files: ${skippedVersions
.sort((a, b) => compareVersions(a, b))
.join(', ')}`,
);
}
if (generatedVersions.length > 0) {
console.log(
`\n${dryRun ? 'Would generate' : 'Generated'} ${
generatedVersions.length
} new version files: ${generatedVersions
.sort((a, b) => compareVersions(a, b))
.join(', ')}`,
);
}
return versionFiles;
}
/**
* Generate main changelog.ts that imports and spreads all version files
*/
async function generateMainChangelog(
versionFiles,
changelogPath,
dryRun = false,
) {
// Get the changelogs directory path
const changelogsDir = path.join(path.dirname(changelogPath), 'changelogs');
// Read all version files from the changelogs directory
const allVersionFiles = new Map();
// First, add all files from the directory (if it exists)
if (fs.existsSync(changelogsDir)) {
const files = fs.readdirSync(changelogsDir);
files.forEach(file => {
if (file.match(/^v\d+\.\d+\.\d+\.ts$/)) {
const version = file.replace(/^v/, '').replace(/\.ts$/, '');
const varName = `changelog_${version.replace(/\./g, '_')}`;
allVersionFiles.set(version, {
version,
fileName: file,
varName,
});
}
});
}
// Then, add/update with files from this run (in case new ones were generated)
versionFiles.forEach(vf => {
allVersionFiles.set(vf.version, {
version: vf.version,
fileName: vf.fileName,
varName: vf.varName,
});
});
// Sort versions in descending order
const sortedVersions = Array.from(allVersionFiles.values()).sort((a, b) =>
compareVersions(b.version, a.version),
);
const imports = sortedVersions
.map(
v =>
`import { ${v.varName} } from './changelogs/${v.fileName.replace(
'.ts',
'',
)}';`,
)
.join('\n');
const spreads = sortedVersions.map(v => ` ...${v.varName},`).join('\n');
const content = `export * from './types';
${imports}
export const changelog = [
${spreads}
];
`;
console.log(
`\n📝 Main changelog.ts will import all ${sortedVersions.length} version files`,
);
if (!dryRun) {
fs.writeFileSync(changelogPath, content, 'utf-8');
}
return content;
}
/**
* Check if an entry already exists in changelog.ts
*/
function isDuplicate(entry, existingContent) {
// Simple check: look for version + description substring
const descStart = entry.description.substring(0, 50);
const pattern = `version: '${entry.version}'`;
const versionIndex = existingContent.indexOf(pattern);
if (versionIndex === -1) return false;
// Check if description appears near this version
const contextWindow = existingContent.substring(
Math.max(0, versionIndex - 200),
versionIndex + 500,
);
return contextWindow.includes(descStart);
}
/**
* Detect GitHub authentication method
* Priority: gh CLI → GITHUB_TOKEN env → unauthenticated
*/
function getGitHubAuth() {
// 1. Try gh CLI (preferred - uses keyring auth)
try {
// Check specifically for github.com authentication
const output = execSync('gh auth status -h github.com 2>&1', {
encoding: 'utf-8',
});
if (output.includes('Logged in to github.com')) {
console.log('✓ Using gh CLI authentication');
return { method: 'gh-cli' };
}
} catch {
// gh not installed or not authenticated to github.com
}
// 2. Try GITHUB_TOKEN env var
if (process.env.GITHUB_TOKEN) {
console.log('✓ Using GITHUB_TOKEN authentication');
return { method: 'token', token: process.env.GITHUB_TOKEN };
}
// 3. Fallback to unauthenticated (60 req/hour limit)
console.warn('⚠️ Using unauthenticated GitHub API (60 requests/hour)');
console.warn(' For higher limits: authenticate gh CLI or set GITHUB_TOKEN');
return { method: 'unauthenticated' };
}
// Initialize auth and Octokit
const githubAuth = getGitHubAuth();
const octokit =
githubAuth.method === 'token'
? new Octokit({ auth: githubAuth.token })
: new Octokit();
// Cache for PR lookups
const prCache = new Map();
/**
* Expand a truncated SHA to full SHA using local git repository
* Falls back to GitHub API if git rev-parse fails
*/
async function expandCommitSha(shortSha) {
try {
// First try local git repository (fastest, works for all commits)
// We need to run this from the backstage monorepo root
const repoRoot = path.join(__dirname, '../../');
try {
const fullSha = execSync(`git rev-parse ${shortSha}`, {
encoding: 'utf-8',
cwd: repoRoot,
stdio: ['pipe', 'pipe', 'pipe'],
}).trim();
if (fullSha && fullSha.length === 40) {
return fullSha;
}
} catch (gitError) {
// Handle ambiguous SHA - parse git's error output to find commit candidates
if (gitError.stderr && gitError.stderr.includes('ambiguous')) {
const stderr = gitError.stderr.toString();
// Extract commit SHAs from git's hint output
// Format: "hint: 83c100e6accfb commit 2025-10-22 - message"
const commitMatch = stderr.match(/hint:\s+([a-f0-9]+)\s+commit\s+/);
if (commitMatch && commitMatch[1]) {
// Found the commit SHA from the ambiguous candidates
const candidateSha = commitMatch[1];
// Verify this is a valid commit
try {
const fullSha = execSync(`git rev-parse ${candidateSha}`, {
encoding: 'utf-8',
cwd: repoRoot,
}).trim();
if (fullSha && fullSha.length === 40) {
return fullSha;
}
} catch {
// Candidate didn't work, continue to GitHub API
}
}
}
// Commit not in local repo, try GitHub API
}
} catch (error) {
// Error setting up git command, try GitHub API
}
try {
// Fallback to GitHub API
if (githubAuth.method === 'gh-cli') {
const result = execSync(
`gh api repos/backstage/backstage/commits/${shortSha} --jq '.sha' 2>/dev/null`,
{ encoding: 'utf-8' },
).trim();
return result || null;
} else {
// Use Octokit
const { data: commit } = await octokit.rest.repos.getCommit({
owner: 'backstage',
repo: 'backstage',
ref: shortSha,
});
return commit.sha;
}
} catch (error) {
// Commit not found or other error - return null silently
return null;
}
}
/**
* Find PR number for a commit SHA using GitHub API
*/
async function findPRNumber(commitSha) {
// Check cache first
if (prCache.has(commitSha)) {
return prCache.get(commitSha);
}
try {
// If SHA is truncated (7 chars), expand it first
let fullSha = commitSha;
if (commitSha.length === 7) {
fullSha = await expandCommitSha(commitSha);
if (!fullSha) {
// Commit not found
console.warn(`⚠️ Commit not found: ${commitSha}`);
prCache.set(commitSha, null);
return null;
}
}
let prNumber = null;
// Use gh CLI if available (faster, uses existing auth)
if (githubAuth.method === 'gh-cli') {
try {
const result = execSync(
`gh api repos/backstage/backstage/commits/${fullSha}/pulls --jq '.[0].number' 2>/dev/null`,
{ encoding: 'utf-8' },
).trim();
prNumber = result || null;
} catch (ghError) {
// Handle gh CLI errors gracefully - commit exists but has no PR
prNumber = null;
}
} else {
// Otherwise use Octokit (token or unauthenticated)
const { data: prs } =
await octokit.rest.repos.listPullRequestsAssociatedWithCommit({
owner: 'backstage',
repo: 'backstage',
commit_sha: fullSha,
});
prNumber = prs.length > 0 ? prs[0].number.toString() : null;
}
// Cache the result
prCache.set(commitSha, prNumber);
return prNumber;
} catch (error) {
if (error.message?.includes('rate limit')) {
console.error('⚠️ GitHub API rate limit exceeded');
console.error(
' Authenticate gh CLI or set GITHUB_TOKEN for higher limits',
);
} else {
console.warn(`⚠️ Error finding PR for ${commitSha}: ${error.message}`);
}
prCache.set(commitSha, null);
return null;
}
}
/**
* Main sync function
*/
async function main() {
const args = process.argv.slice(2);
const dryRun = args.includes('--dry-run');
const changelogTsPath = path.join(__dirname, '../src/utils/changelog.ts');
const changelogMdPath = path.join(
__dirname,
'../../packages/ui/CHANGELOG.md',
);
// Validate files exist
if (!fs.existsSync(changelogTsPath)) {
throw new Error(`changelog.ts not found at: ${changelogTsPath}`);
}
if (!fs.existsSync(changelogMdPath)) {
throw new Error(`CHANGELOG.md not found at: ${changelogMdPath}`);
}
console.log('📋 Syncing UI component changelogs...\n');
// Get last synced version
const lastVersion = getLastSyncedVersion(changelogTsPath);
console.log(`Last synced version: ${lastVersion || '(none)'}`);
// Get valid components
const validComponents = getValidComponents(changelogTsPath);
console.log(`Valid components: ${validComponents.length}`);
// Parse CHANGELOG.md
console.log('\n📖 Parsing CHANGELOG.md...');
const allEntries = await parseChangelogMd(
changelogMdPath,
lastVersion,
validComponents,
);
console.log(`Found ${allEntries.length} total entries since ${lastVersion}`);
// Read existing changelog content for duplicate detection
const existingContent = fs.readFileSync(changelogTsPath, 'utf-8');
// Filter to only new, non-duplicate entries
const relevantEntries = allEntries.filter(e => {
const hasComponents = e.components.length > 0 || e.components.length === 0;
const notDuplicate = !isDuplicate(e, existingContent);
return hasComponents && notDuplicate;
});
const duplicatesCount = allEntries.length - relevantEntries.length;
if (duplicatesCount > 0) {
console.log(`Skipped ${duplicatesCount} duplicate entries`);
}
console.log(
`Relevant entries (with or without components): ${relevantEntries.length}`,
);
if (relevantEntries.length === 0) {
console.log('\n✅ No new entries to sync');
return;
}
// Fetch PR numbers for new entries (lazy fetch - only for entries that will be written)
await fetchPRNumbers(relevantEntries, dryRun);
// Show summary
console.log('\n📝 New entries by component:');
const byComponent = {};
relevantEntries.forEach(entry => {
if (entry.components.length === 0) {
byComponent['(general)'] = (byComponent['(general)'] || 0) + 1;
} else {
entry.components.forEach(comp => {
byComponent[comp] = (byComponent[comp] || 0) + 1;
});
}
});
Object.entries(byComponent).forEach(([comp, count]) => {
console.log(` - ${comp}: ${count} ${count === 1 ? 'entry' : 'entries'}`);
});
// Warn about unknown components
const unknownComponents = [];
allEntries.forEach(entry => {
const fullText = entry.description;
const componentMatch = fullText.match(
/Affected components?:[ \t]*([^\n]+)/i,
);
if (componentMatch) {
const names = componentMatch[1].split(',').map(n => n.trim());
names.forEach(name => {
if (!mapComponentName(name, validComponents)) {
unknownComponents.push(name);
}
});
}
});
if (unknownComponents.length > 0) {
console.log('\n⚠️ Unknown components (skipped):');
[...new Set(unknownComponents)].forEach(name => {
console.log(` - ${name}`);
});
}
// Create changelogs directory if it doesn't exist
const changelogsDir = path.join(__dirname, '../src/utils/changelogs');
if (!fs.existsSync(changelogsDir) && !dryRun) {
fs.mkdirSync(changelogsDir, { recursive: true });
}
// Generate version files
console.log(
`\n${
dryRun ? '🔍 Dry run - would generate' : '✍️ Generating'
} version files...`,
);
const versionFiles = await generateVersionFiles(
relevantEntries,
changelogsDir,
dryRun,
);
// Generate main changelog.ts
const mainContent = await generateMainChangelog(
versionFiles,
changelogTsPath,
dryRun,
);
if (!dryRun) {
console.log('\n✅ Changelog sync complete!');
const newFiles = versionFiles.filter(vf => !vf.skipped).length;
const skippedFiles = versionFiles.filter(vf => vf.skipped).length;
if (newFiles > 0) {
console.log(
` Generated ${newFiles} new version file${newFiles === 1 ? '' : 's'}`,
);
}
if (skippedFiles > 0) {
console.log(
` Preserved ${skippedFiles} existing version file${
skippedFiles === 1 ? '' : 's'
}`,
);
}
console.log(` Updated ${changelogTsPath}`);
} else {
console.log('\n📄 Sample version file content:\n');
// Find first non-skipped version file for sample
const sampleFile = versionFiles.find(vf => !vf.skipped && vf.content);
if (sampleFile) {
const sample = sampleFile.content.split('\n').slice(0, 30).join('\n');
console.log(sample);
console.log('...\n');
} else {
console.log('(No new version files to generate)\n');
}
console.log('\n📄 Main changelog.ts content:\n');
console.log(mainContent);
const newFiles = versionFiles.filter(vf => !vf.skipped).length;
const skippedFiles = versionFiles.filter(vf => vf.skipped).length;
console.log('\n✅ Dry run complete - no files were modified');
if (newFiles > 0) {
console.log(
` Run without --dry-run to generate ${newFiles} new version file${
newFiles === 1 ? '' : 's'
}`,
);
}
if (skippedFiles > 0) {
console.log(
` ${skippedFiles} existing version file${
skippedFiles === 1 ? '' : 's'
} will be preserved`,
);
}
}
}
// Run main if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
main().catch(error => {
console.error('❌ Error:', error.message);
process.exit(1);
});
}
+9 -8
View File
@@ -52,14 +52,15 @@ export function Changelog() {
${bumpEntries
.map(e => {
const prs =
e.prs.length > 0 &&
e.prs
.map(
pr =>
`[#${pr}](https://github.com/backstage/backstage/pull/${pr})`,
)
.join(', ');
return `- ${e.description} ${prs}`;
e.prs.length > 0
? e.prs
.map(
pr =>
`[#${pr}](https://github.com/backstage/backstage/pull/${pr})`,
)
.join(', ')
: '';
return `- ${e.description}${prs ? ` ${prs}` : ''}`;
})
.join('\n')}`;
})
@@ -17,14 +17,17 @@ export const ChangelogComponent = ({ component }: { component: Component }) => {
${componentChangelog
?.map(change => {
const prs =
change.prs.length > 0 &&
change.prs
.map(
pr =>
`[#${pr}](https://github.com/backstage/backstage/pull/${pr})`,
)
.join(', ');
return `- \`${change.version}\` - ${change.description} ${prs}`;
change.prs.length > 0
? change.prs
.map(
pr =>
`[#${pr}](https://github.com/backstage/backstage/pull/${pr})`,
)
.join(', ')
: '';
return `- \`${change.version}\` - ${change.description}${
prs ? ` ${prs}` : ''
}`;
})
.join('\n')}`}
/>
+7 -12
View File
@@ -1,18 +1,13 @@
import { MDXRemote } from 'next-mdx-remote-client/rsc';
import { formattedMDXComponents } from '@/mdx-components';
import { Component } from '@/utils/changelog';
import { componentDefinitions } from '../../../../packages/ui/src/utils/componentDefinitions';
import type { DataAttributeValues } from '../../../../packages/ui/src/types';
import type {
ComponentDefinition,
DataAttributeValues,
} from '../../../../packages/ui/src/types';
export function Theming({ component }: { component: Component }) {
const componentDefinition = componentDefinitions[component];
if (!componentDefinition) {
return null;
}
const classNames = componentDefinition.classNames;
const dataAttributes = componentDefinition.dataAttributes;
export function Theming({ definition }: { definition: ComponentDefinition }) {
const classNames = definition.classNames;
const dataAttributes = definition.dataAttributes;
// Get the first class name
const firstClassName = Object.values(classNames)[0];
+2 -1
View File
@@ -16,6 +16,7 @@ import {
} from './accordion.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { AccordionDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -123,6 +124,6 @@ Here's a view when multiple accordions can be open simultaneously.
code={accordionGroupMultipleOpenSnippet}
/>
<Theming component="Accordion" />
<Theming definition={AccordionDefinition} />
<ChangelogComponent component="accordion" />
+2 -1
View File
@@ -11,6 +11,7 @@ import {
} from './avatar.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { AvatarDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -70,6 +71,6 @@ Control how the avatar is announced to screen readers using the `purpose` prop.
code={snippetPurpose}
/>
<Theming component="Avatar" />
<Theming definition={AvatarDefinition} />
<ChangelogComponent component="avatar" />
+2 -1
View File
@@ -12,6 +12,7 @@ import {
import { spacingPropDefs } from '@/utils/propDefs';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { BoxDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -60,6 +61,6 @@ Here's a view when buttons are responsive.
<CodeBlock code={boxResponsiveSnippet} />
<Theming component="Box" />
<Theming definition={BoxDefinition} />
<ChangelogComponent component="box" />
+2 -1
View File
@@ -15,6 +15,7 @@ import {
} from './button-icon.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ButtonIconDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -93,6 +94,6 @@ Here's a view when buttons are responsive.
<CodeBlock code={buttonIconResponsiveSnippet} />
<Theming component="ButtonIcon" />
<Theming definition={ButtonIconDefinition} />
<ChangelogComponent component="button-icon" />
+2 -1
View File
@@ -13,6 +13,7 @@ import {
} from './button-link.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ButtonLinkDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -91,6 +92,6 @@ Here's a view when buttons are responsive.
<CodeBlock code={buttonLinkResponsiveSnippet} />
<Theming component="ButtonLink" />
<Theming definition={ButtonLinkDefinition} />
<ChangelogComponent component="button-link" />
+2 -1
View File
@@ -16,6 +16,7 @@ import {
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ButtonDefinition } from '../utils/definitions';
<PageTitle
title="Button"
@@ -117,6 +118,6 @@ If you want to use a button as a link, please use the `ButtonLink` component.
code={buttonAsLinkSnippet}
/>
<Theming component="Button" />
<Theming definition={ButtonDefinition} />
<ChangelogComponent component="button" />
+2 -1
View File
@@ -14,6 +14,7 @@ import {
} from './card.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { CardDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -84,6 +85,6 @@ Here's a view when card has a list.
open
/>
<Theming component="Card" />
<Theming definition={CardDefinition} />
<ChangelogComponent component="card" />
+2 -1
View File
@@ -10,6 +10,7 @@ import {
} from './checkbox.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { CheckboxDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -46,6 +47,6 @@ Here's a view when checkboxes have different variants.
code={checkboxVariantsSnippet}
/>
<Theming component="Checkbox" />
<Theming definition={CheckboxDefinition} />
<ChangelogComponent component="checkbox" />
+2 -1
View File
@@ -11,6 +11,7 @@ import {
} from './container.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ContainerDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -48,6 +49,6 @@ create responsive designs.
<CodeBlock code={containerResponsiveSnippet} />
<Theming component="Container" />
<Theming definition={ContainerDefinition} />
<ChangelogComponent component="container" />
+2 -1
View File
@@ -18,6 +18,7 @@ import {
} from './dialog.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { DialogDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -102,6 +103,6 @@ You can also control the dialog using your own states.
<CodeBlock code={dialogWithNoTriggerSnippet} />
<Theming component="Dialog" />
<Theming definition={DialogDefinition} />
<ChangelogComponent component="dialog" />
+2 -1
View File
@@ -14,6 +14,7 @@ import {
import { spacingPropDefs } from '@/utils/propDefs';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { FlexDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -63,6 +64,6 @@ create responsive designs.
<CodeBlock code={flexAlignSnippet} />
<Theming component="Flex" />
<Theming definition={FlexDefinition} />
<ChangelogComponent component="flex" />
+2 -1
View File
@@ -16,6 +16,7 @@ import {
} from './grid.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { GridDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -93,6 +94,6 @@ The start and end props can be used to position the item in the grid.
<CodeBlock code={gridStartEndSnippet} />
<Theming component="Grid" />
<Theming definition={GridDefinition} />
<ChangelogComponent component="grid" />
+2 -1
View File
@@ -14,6 +14,7 @@ import {
} from './header-page.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { HeaderPageDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -82,6 +83,6 @@ prop is an array of objects with a `label`, `value` and `onClick` property.
code={withMenuItems}
/>
<Theming component="HeaderPage" />
<Theming definition={HeaderPageDefinition} />
<ChangelogComponent component="Header" />
+2 -1
View File
@@ -13,6 +13,7 @@ import {
} from './header.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { HeaderDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -80,6 +81,6 @@ You can use the `Header` component inside the [HeaderPage](/components/header-pa
open
/>
<Theming component="Header" />
<Theming definition={HeaderDefinition} />
<ChangelogComponent component="Header" />
+2 -1
View File
@@ -19,6 +19,7 @@ import {
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { LinkDefinition } from '../utils/definitions';
<PageTitle
title="Link"
@@ -97,6 +98,6 @@ The `Link` component has a `truncate` prop that can be used to truncate the text
code={linkTruncateSnippet}
/>
<Theming component="Link" />
<Theming definition={LinkDefinition} />
<ChangelogComponent component="link" />
+2 -1
View File
@@ -27,6 +27,7 @@ import {
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { MenuDefinition } from '../utils/definitions';
<PageTitle
title="Menu"
@@ -231,6 +232,6 @@ allow multiple selection.
code={autocompleteListboxMultiple}
/>
<Theming component="Menu" />
<Theming definition={MenuDefinition} />
<ChangelogComponent component="menu" />
+2 -1
View File
@@ -12,6 +12,7 @@ import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { CodeBlock } from '@/components/CodeBlock';
import { PasswordFieldDefinition } from '../utils/definitions';
<PageTitle
title="PasswordField"
@@ -59,6 +60,6 @@ Here's a simple PasswordField with a description.
code={passwordFieldDescriptionSnippet}
/>
<Theming component="PasswordField" />
<Theming definition={PasswordFieldDefinition} />
<ChangelogComponent component="password-field" />
+2 -1
View File
@@ -16,6 +16,7 @@ import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { CodeBlock } from '@/components/CodeBlock';
import { RadioGroupDefinition } from '../utils/definitions';
<PageTitle
title="RadioGroup"
@@ -99,6 +100,6 @@ You can make the radio group read only by adding the `isReadOnly` prop to the `R
code={radioGroupReadOnlySnippet}
/>
<Theming component="RadioGroup" />
<Theming definition={RadioGroupDefinition} />
<ChangelogComponent component="radio-group" />
+2 -1
View File
@@ -13,6 +13,7 @@ import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { CodeBlock } from '@/components/CodeBlock';
import { SearchFieldDefinition } from '../utils/definitions';
<PageTitle
title="SearchField"
@@ -72,6 +73,6 @@ You can make the SearchField collapsible by setting the `startCollapsed` prop to
code={searchFieldCollapsibleSnippet}
/>
<Theming component="SearchField" />
<Theming definition={SearchFieldDefinition} />
<ChangelogComponent component="search-field" />
+2 -1
View File
@@ -18,6 +18,7 @@ import {
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { SelectDefinition } from '../utils/definitions';
<PageTitle
title="Select"
@@ -132,6 +133,6 @@ Here's a view when the select is responsive.
<CodeBlock code={selectResponsiveSnippet} />
<Theming component="Select" />
<Theming definition={SelectDefinition} />
<ChangelogComponent component="select" />
+2 -1
View File
@@ -12,6 +12,7 @@ import {
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { SkeletonDefinition } from '../utils/definitions';
<PageTitle
title="Skeleton"
@@ -59,6 +60,6 @@ You can use a mix of different sizes to create a more complex skeleton.
open
/>
<Theming component="Skeleton" />
<Theming definition={SkeletonDefinition} />
<ChangelogComponent component="skeleton" />
+2 -1
View File
@@ -6,6 +6,7 @@ import { switchPropDefs, snippetUsage } from './switch.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { SwitchDefinition } from '../utils/definitions';
<PageTitle
title="Switch"
@@ -41,6 +42,6 @@ A switch can be disabled using the `isDisabled` prop.
code={`<Switch isDisabled />`}
/>
<Theming component="Switch" />
<Theming definition={SwitchDefinition} />
<ChangelogComponent component="switch" />
+2 -1
View File
@@ -22,6 +22,7 @@ import {
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { TableDefinition } from '../utils/definitions';
<PageTitle
title="Table"
@@ -128,6 +129,6 @@ This feature is not available yet — let us know if you'd like us to explore it
This feature is not available yet — let us know if you'd like us to explore it!
<Theming component="Table" />
<Theming definition={TableDefinition} />
<ChangelogComponent component="table" />
+2 -1
View File
@@ -13,6 +13,7 @@ import {
} from './tabs.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { TabsDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -79,6 +80,6 @@ You can use the `matchStrategy` prop on the tab to control how the tab is matche
open
/>
<Theming component="Tabs" />
<Theming definition={TabsDefinition} />
<ChangelogComponent component="tabs" />
+2 -1
View File
@@ -15,6 +15,7 @@ import {
} from './tag-group.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { TagGroupDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -109,6 +110,6 @@ A switch can be disabled using the `isDisabled` prop.
code={disabled}
/>
<Theming component="Switch" />
<Theming definition={TagGroupDefinition} />
<ChangelogComponent component="switch" />
+2 -1
View File
@@ -10,6 +10,7 @@ import {
} from './text-field.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { TextFieldDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
import { CodeBlock } from '@/components/CodeBlock';
@@ -59,6 +60,6 @@ Here's a simple TextField with a description.
code={textFieldDescriptionSnippet}
/>
<Theming component="TextField" />
<Theming definition={TextFieldDefinition} />
<ChangelogComponent component="text-field" />
+2 -1
View File
@@ -14,6 +14,7 @@ import {
} from './text.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { TextDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -87,6 +88,6 @@ on the screen size.
<CodeBlock code={textResponsiveSnippet} />
<Theming component="Text" />
<Theming definition={TextDefinition} />
<ChangelogComponent component="text" />
+2 -1
View File
@@ -10,6 +10,7 @@ import {
} from './tooltip.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { TooltipDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -42,6 +43,6 @@ The tooltip will wrap the content of the tooltip.
<PropsTable data={tooltipPropDefs} />
<Theming component="Tooltip" />
<Theming definition={TooltipDefinition} />
<ChangelogComponent component="tooltip" />
+2 -1
View File
@@ -10,6 +10,7 @@ import {
} from './visually-hidden.props';
import { PageTitle } from '@/components/PageTitle';
import { Theming } from '@/components/Theming';
import { VisuallyHiddenDefinition } from '../utils/definitions';
import { ChangelogComponent } from '@/components/ChangelogComponent';
<PageTitle
@@ -46,6 +47,6 @@ Here's an example of providing screen reader context for a list of links in a fo
open
/>
<Theming component="VisuallyHidden" />
<Theming definition={VisuallyHiddenDefinition} />
<ChangelogComponent component="visually-hidden" />
+28 -536
View File
@@ -1,538 +1,30 @@
export type Component =
| 'avatar'
| 'box'
| 'button'
| 'button-link'
| 'heading'
| 'text'
| 'button-icon'
| 'icon'
| 'tabs'
| 'menu'
| 'textfield'
| 'datatable'
| 'select'
| 'collapsible'
| 'accordion'
| 'checkbox'
| 'container'
| 'link'
| 'tooltip'
| 'scrollarea'
| 'flex'
| 'switch'
| 'grid'
| 'searchfield'
| 'radio-group'
| 'card'
| 'skeleton'
| 'header'
| 'passwordfield';
export * from './types';
import { changelog_0_8_2 } from './changelogs/v0.8.2';
import { changelog_0_8_0 } from './changelogs/v0.8.0';
import { changelog_0_7_2 } from './changelogs/v0.7.2';
import { changelog_0_7_1 } from './changelogs/v0.7.1';
import { changelog_0_7_0 } from './changelogs/v0.7.0';
import { changelog_0_6_0 } from './changelogs/v0.6.0';
import { changelog_0_5_0 } from './changelogs/v0.5.0';
import { changelog_0_4_0 } from './changelogs/v0.4.0';
import { changelog_0_3_2 } from './changelogs/v0.3.2';
import { changelog_0_3_0 } from './changelogs/v0.3.0';
import { changelog_0_2_1 } from './changelogs/v0.2.1';
import { changelog_0_2_0 } from './changelogs/v0.2.0';
import { changelog_0_1_0 } from './changelogs/v0.1.0';
export type Version = `${number}.${number}.${number}`;
export interface ChangelogProps {
components: Component[];
description: string;
version: Version;
prs: string[];
type?: 'breaking' | 'new' | 'fix';
}
export const changelog: ChangelogProps[] = [
{
components: ['tooltip'],
version: '0.6.0',
description: 'New `Tooltip` component.',
prs: ['30461'],
type: 'new',
},
{
components: ['card'],
version: '0.6.0',
description: 'New `Card` component.',
prs: ['30467'],
type: 'new',
},
{
components: ['header'],
version: '0.6.0',
description: 'New `Header` component.',
prs: ['30410', '30459', '30493'],
type: 'new',
},
{
components: ['button', 'button-link', 'button-icon'],
version: '0.6.0',
description: 'Improve `Button`, `ButtonIcon` and `ButtonLink` styling.',
prs: ['30448'],
type: 'fix',
},
{
components: ['text', 'heading'],
version: '0.6.0',
description:
'Update return types for `Heading` & `Text` components for React 19.',
prs: ['30440'],
type: 'fix',
},
{
components: ['button', 'button-link', 'button-icon'],
version: '0.6.0',
description:
'New `tertiary` variant to `Button`, `ButtonIcon` and `ButtonLink`.',
prs: ['30453'],
type: 'new',
},
{
components: ['skeleton'],
version: '0.6.0',
description: 'New `Skeleton` component.',
prs: ['30466'],
type: 'new',
},
{
components: ['button-icon'],
version: '0.6.0',
description: 'Rename `IconButton` to `ButtonIcon`.',
prs: ['30297'],
type: 'breaking',
},
{
components: ['button-link'],
version: '0.6.0',
description:
'New `ButtonLink`, which replaces the previous render prop pattern on `Button` and `IconButton`.',
prs: ['30297'],
type: 'new',
},
{
components: ['button', 'button-link', 'button-icon'],
version: '0.6.0',
description: 'Remove the `render` prop from all button-related components.',
prs: ['30297'],
type: 'breaking',
},
{
components: [],
version: '0.6.0',
description: 'We are consolidating all css files into a single styles.css.',
prs: ['30325'],
type: 'fix',
},
{
components: ['searchfield'],
version: '0.6.0',
description: 'New `SearchField` component.',
prs: ['30357'],
type: 'new',
},
{
components: ['radio-group'],
version: '0.6.0',
description: 'New `RadioGroup` + `Radio` component.',
prs: ['30327'],
type: 'new',
},
{
components: ['textfield'],
version: '0.6.0',
description: 'Added placeholder prop back to `TextField` component.',
prs: ['30286'],
type: 'fix',
},
{
components: ['textfield'],
version: '0.5.0',
description: '`TextField` now has multiple label sizes.',
prs: ['30249'],
type: 'breaking',
},
{
components: ['textfield'],
version: '0.5.0',
description:
'`TextField` can now hide label and description while keeping them available for screen readers.',
prs: ['30249'],
type: 'breaking',
},
{
components: ['textfield'],
version: '0.5.0',
description:
'We are removing the `render` prop in favour of the `as` prop on `Heading` and `Text`.',
prs: ['30291'],
type: 'breaking',
},
{
components: ['textfield'],
version: '0.5.0',
description: 'Move `TextField` component to use react Aria under the hood.',
prs: ['30286'],
type: 'breaking',
},
{
components: ['button', 'button-link'],
version: '0.5.0',
description:
'Added a render prop to the `Button` component to use it as a link.',
prs: ['30165'],
type: 'new',
},
{
components: ['heading'],
version: '0.5.0',
description: 'Fix styling for the title4 prop on the Heading component.',
prs: ['30167'],
type: 'fix',
},
{
components: ['flex'],
version: '0.5.0',
description:
'Add `min-width: 0;` by default on Flex components to support truncated text.',
prs: ['30168'],
type: 'fix',
},
{
components: ['button', 'button-link', 'button-icon'],
version: '0.5.0',
description:
'`Button`, `ButtonLink`, `ButtonIcon` now default to size `small` instead of `medium`',
prs: ['30085', '30097'],
type: 'breaking',
},
{
components: ['grid'],
version: '0.5.0',
description: 'Rename Grid component to `<Grid.Root />`',
prs: ['30013'],
type: 'breaking',
},
{
components: ['flex', 'container', 'grid', 'box'],
version: '0.5.0',
description: 'Fixes spacing props on layout components',
prs: ['30013'],
type: 'fix',
},
{
components: ['switch'],
version: '0.5.0',
description: 'New `Switch` component',
prs: ['30251'],
type: 'new',
},
{
components: ['tabs'],
version: '0.4.0',
description: 'New `Tabs` component',
prs: ['29996'],
type: 'new',
},
{
components: ['text', 'heading'],
version: '0.4.0',
description: 'Add `truncate` prop to `Text` and `Heading`',
prs: ['29988'],
type: 'new',
},
{
components: ['menu'],
version: '0.4.0',
description: 'Add combobox option to `Menu`',
prs: ['29986'],
type: 'new',
},
{
components: ['textfield'],
version: '0.4.0',
description: 'Add icon prop on `TextField`',
prs: ['29820'],
type: 'new',
},
{
components: ['button', 'button-icon'],
version: '0.4.0',
description: 'Improve icon props on `Button` and `IconButton`',
prs: ['29667'],
},
{
components: ['text', 'heading'],
version: '0.4.0',
description:
'Improve the way we treat custom render on `Text` and `Heading`',
prs: ['29989'],
},
{
components: ['menu'],
version: '0.4.0',
description: 'Improve `Menu` styles',
prs: ['29986'],
},
{
components: ['textfield'],
version: '0.4.0',
description: 'Improve `TextField` styles',
prs: ['29974'],
},
{
components: ['textfield'],
version: '0.4.0',
description: 'Improve clear button on `TextField`',
prs: ['29878'],
},
{
components: ['flex'],
version: '0.4.0',
description: 'Fix spacing props on all layout components',
prs: ['30013'],
},
{
components: [],
version: '0.4.0',
description: 'Fix - Pin Base UI version',
prs: ['29782'],
},
{
components: ['select'],
version: '0.4.0',
description: 'Fix - Clicking `Select` label moves focus to trigger',
prs: ['29755'],
},
{
components: ['datatable'],
version: '0.4.0',
description: 'Fix `DataTable.Pagination` count issue',
prs: ['29688'],
},
{
components: ['datatable'],
version: '0.3.0',
description: 'Add `DataTable` component',
prs: ['29484', '29603'],
type: 'new',
},
{
components: ['select'],
version: '0.3.0',
description: 'Add `Select` component',
prs: ['29440'],
type: 'new',
},
{
components: ['avatar'],
version: '0.3.0',
description: 'Add `Avatar` component',
prs: ['29594'],
type: 'new',
},
{
components: ['collapsible'],
version: '0.3.0',
description: 'Add `Collapsible` component',
prs: ['29617'],
type: 'new',
},
{
components: ['textfield'],
version: '0.3.0',
description: 'Add `TextField` component instead of `Field` + `Input`',
prs: ['29364'],
type: 'new',
},
{
components: ['datatable'],
version: '0.3.0',
description: 'Add `TableCellProfile`',
prs: ['29600'],
type: 'new',
},
{
components: [],
version: '0.3.0',
description: 'Add breakpoint hooks - `up()` and `down()`',
prs: ['29564'],
type: 'new',
},
{
components: [],
version: '0.3.0',
description: 'Add gray scale css tokens',
prs: ['29543'],
type: 'new',
},
{
components: [],
version: '0.3.0',
description:
'Update CSS styling API using `[data-___]` instead of class names for props',
prs: ['29560'],
},
{
components: ['checkbox'],
version: '0.3.0',
description: 'Update `Checkbox` dark mode',
prs: ['29544'],
},
{
components: ['container'],
version: '0.3.0',
description: 'Update `Container` styles',
prs: ['29475'],
},
{
components: ['menu'],
version: '0.3.0',
description: 'Update `Menu` styles',
prs: ['29351'],
},
{
components: ['select'],
version: '0.3.0',
description: 'Fix `Select` styles on small sizes + with long option names',
prs: ['29545'],
},
{
components: ['link'],
version: '0.3.0',
description: 'Fix render prop on `Link`',
prs: ['29247'],
},
{
components: ['textfield', 'select'],
version: '0.3.0',
description: 'Remove `Field` from `TextField` + `Select`',
prs: ['29482'],
},
{
components: ['text', 'heading'],
version: '0.3.0',
description: 'Update `textDecoration` to `none` on `Text` / `Heading`',
prs: ['29357'],
},
{
components: ['text', 'heading'],
version: '0.3.0',
description: 'Update `textDecoration` to `none` on `Text` / `Heading`',
prs: ['29357'],
},
{
components: [],
version: '0.3.0',
description: 'Docs - Use stories from Storybook for all examples in Nextjs',
prs: ['29306'],
},
{
components: [],
version: '0.3.0',
description: 'Docs - Add release page (this one 🤗)',
prs: ['29461'],
},
{
components: [],
version: '0.3.0',
description: 'Docs - Add docs for Menu, Link',
prs: ['29576'],
},
{
components: [],
version: '0.3.0',
description: 'Fix CSS watch mode',
prs: ['29352'],
},
{
components: ['menu'],
version: '0.2.0',
description: 'New `Menu` component',
prs: ['29151'],
type: 'new',
},
{
components: ['button-icon'],
version: '0.2.0',
description: 'New `IconButton` component',
prs: ['29239'],
type: 'new',
},
{
components: ['scrollarea'],
version: '0.2.0',
description: 'New `ScrollArea` component',
prs: ['29240'],
type: 'new',
},
{
components: ['button', 'checkbox'],
version: '0.2.0',
description: 'Improve `Button` & `Checkbox` styles',
prs: ['29127', '28789'],
},
{
components: ['text'],
version: '0.2.0',
description: 'Improve `Text` styles',
prs: ['29200'],
},
{
components: ['icon'],
version: '0.2.0',
description: 'Renamed `CanonProvider` to `IconProvider`',
prs: ['29002'],
},
{
components: ['icon'],
version: '0.2.0',
description: 'Added about 40+ new icons',
prs: ['29264'],
},
{
components: [],
version: '0.2.0',
description: 'Simplified styling into a unique styles.css file',
prs: ['29199'],
},
{
components: [],
version: '0.2.0',
description: 'Added global styles to Backstage',
prs: ['29137'],
type: 'new',
},
{
components: [],
version: '0.2.0',
description: 'Update global CSS tokens',
prs: ['28804'],
},
{
components: ['flex'],
version: '0.2.0',
description: 'Merge Stack + Inline into Flex',
prs: ['28634'],
},
{
components: ['button'],
version: '0.2.0',
description: 'Improve `Button` types',
prs: ['29205'],
},
{
components: [],
version: '0.2.0',
description: 'Move font weight and family back to each components',
prs: ['28972'],
},
{
components: [],
version: '0.2.0',
description: 'Fix custom values in spacing props',
prs: ['28770'],
},
{
components: [],
version: '0.2.0',
description: 'Multiple updates on the docs site',
prs: ['28760'],
},
export const changelog = [
...changelog_0_8_2,
...changelog_0_8_0,
...changelog_0_7_2,
...changelog_0_7_1,
...changelog_0_7_0,
...changelog_0_6_0,
...changelog_0_5_0,
...changelog_0_4_0,
...changelog_0_3_2,
...changelog_0_3_0,
...changelog_0_2_1,
...changelog_0_2_0,
...changelog_0_1_0,
];
+116
View File
@@ -0,0 +1,116 @@
import type { ChangelogProps } from '../types';
export const changelog_0_1_0: ChangelogProps[] = [
{
components: [],
version: '0.1.0',
description: `**BREAKING**: Merged the Stack and Inline component into a single component called Flex.`,
prs: ['28634'],
type: 'breaking',
commitSha: '72c9800',
},
{
components: [],
version: '0.1.0',
description: `This is the first alpha release for Canon. As part of this release we are introducing 5 layout components and 7 components. All theming is done through CSS variables.`,
prs: ['28562'],
type: 'breaking',
commitSha: '65f4acc',
},
{
components: [],
version: '0.1.0',
description: `**BREAKING**: Fixing css structure and making sure that props are applying the correct styles for all responsive values.`,
prs: ['28630'],
type: 'breaking',
commitSha: '1e4ccce',
},
{
components: [],
version: '0.1.0',
description: `Updated core CSS tokens and fixing the Button component accordingly.`,
prs: ['28789'],
type: 'breaking',
commitSha: '8309bdb',
},
{
components: [],
version: '0.1.0',
description: `Removed client directive as they are not needed in React 18.`,
prs: ['28626'],
type: 'fix',
commitSha: '989af25',
},
{
components: [],
version: '0.1.0',
description: `Fix spacing props not being applied for custom values.`,
prs: ['28770'],
type: 'fix',
commitSha: 'f44e5cf',
},
{
components: [],
version: '0.1.0',
description: `Removed older versions of React packages as a preparatory step for upgrading to React 19. This commit does not introduce any functional changes, but removes dependencies on previous React versions, allowing for a cleaner upgrade path in subsequent commits.`,
prs: ['28579'],
type: 'fix',
commitSha: '58ec9e7',
},
{
components: [],
version: '0.1.0',
description: `Updated core CSS tokens and fixing the Button component accordingly.`,
prs: ['28789'],
type: 'breaking',
commitSha: '8309bdb',
},
{
components: [],
version: '0.1.0',
description: `Fix spacing props not being applied for custom values.`,
prs: ['28770'],
type: 'fix',
commitSha: 'f44e5cf',
},
{
components: [],
version: '0.1.0',
description: `**BREAKING**: Merged the Stack and Inline component into a single component called Flex.`,
prs: ['28634'],
type: 'breaking',
commitSha: '72c9800',
},
{
components: [],
version: '0.1.0',
description: `**BREAKING**: Fixing css structure and making sure that props are applying the correct styles for all responsive values.`,
prs: ['28630'],
type: 'breaking',
commitSha: '1e4ccce',
},
{
components: [],
version: '0.1.0',
description: `Removed client directive as they are not needed in React 18.`,
prs: ['28626'],
type: 'fix',
commitSha: '989af25',
},
{
components: [],
version: '0.1.0',
description: `Removed older versions of React packages as a preparatory step for upgrading to React 19. This commit does not introduce any functional changes, but removes dependencies on previous React versions, allowing for a cleaner upgrade path in subsequent commits.`,
prs: ['28579'],
type: 'fix',
commitSha: '58ec9e7',
},
{
components: [],
version: '0.1.0',
description: `This is the first alpha release for Canon. As part of this release we are introducing 5 layout components and 7 components. All theming is done through CSS variables.`,
prs: ['28562'],
type: 'breaking',
commitSha: '65f4acc',
},
];
+98
View File
@@ -0,0 +1,98 @@
import type { ChangelogProps } from '../types';
export const changelog_0_2_0: ChangelogProps[] = [
{
components: ['menu'],
version: '0.2.0',
description: 'New `Menu` component',
prs: ['29151'],
type: 'new',
},
{
components: ['button-icon'],
version: '0.2.0',
description: 'New `IconButton` component',
prs: ['29239'],
type: 'new',
},
{
components: ['scrollarea'],
version: '0.2.0',
description: 'New `ScrollArea` component',
prs: ['29240'],
type: 'new',
},
{
components: ['button', 'checkbox'],
version: '0.2.0',
description: 'Improve `Button` & `Checkbox` styles',
prs: ['29127', '28789'],
},
{
components: ['text'],
version: '0.2.0',
description: 'Improve `Text` styles',
prs: ['29200'],
},
{
components: ['icon'],
version: '0.2.0',
description: 'Renamed `CanonProvider` to `IconProvider`',
prs: ['29002'],
},
{
components: ['icon'],
version: '0.2.0',
description: 'Added about 40+ new icons',
prs: ['29264'],
},
{
components: [],
version: '0.2.0',
description: 'Simplified styling into a unique styles.css file',
prs: ['29199'],
},
{
components: [],
version: '0.2.0',
description: 'Added global styles to Backstage',
prs: ['29137'],
type: 'new',
},
{
components: [],
version: '0.2.0',
description: 'Update global CSS tokens',
prs: ['28804'],
},
{
components: ['flex'],
version: '0.2.0',
description: 'Merge Stack + Inline into Flex',
prs: ['28634'],
},
{
components: ['button'],
version: '0.2.0',
description: 'Improve `Button` types',
prs: ['29205'],
},
{
components: [],
version: '0.2.0',
description: 'Move font weight and family back to each components',
prs: ['28972'],
},
{
components: [],
version: '0.2.0',
description: 'Fix custom values in spacing props',
prs: ['28770'],
},
{
components: [],
version: '0.2.0',
description: 'Multiple updates on the docs site',
prs: ['28760'],
},
];
+44
View File
@@ -0,0 +1,44 @@
import type { ChangelogProps } from '../types';
export const changelog_0_2_1: ChangelogProps[] = [
{
components: [],
version: '0.2.1',
description: `Internal refactor and fixes to the prop extraction logic for layout components.`,
prs: ['29389'],
type: 'fix',
commitSha: 'f7cb538',
},
{
components: [],
version: '0.2.1',
description: `Fix types on the Icon component.`,
prs: ['29306'],
type: 'fix',
commitSha: '5e80f0b',
},
{
components: [],
version: '0.2.1',
description: `Updated styles for the Menu component in Canon.`,
prs: ['29351'],
type: 'fix',
commitSha: '6af7b16',
},
{
components: [],
version: '0.2.1',
description: `Add global CSS reset for anchor tags.`,
prs: ['29357'],
type: 'new',
commitSha: '513477f',
},
{
components: [],
version: '0.2.1',
description: `Fix the Icon component when the name is not found to return null instead of an empty SVG.`,
prs: ['29280'],
type: 'fix',
commitSha: '05a5003',
},
];
+139
View File
@@ -0,0 +1,139 @@
import type { ChangelogProps } from '../types';
export const changelog_0_3_0: ChangelogProps[] = [
{
components: ['datatable'],
version: '0.3.0',
description: 'Add `DataTable` component',
prs: ['29484', '29603'],
type: 'new',
},
{
components: ['select'],
version: '0.3.0',
description: 'Add `Select` component',
prs: ['29440'],
type: 'new',
},
{
components: ['avatar'],
version: '0.3.0',
description: 'Add `Avatar` component',
prs: ['29594'],
type: 'new',
},
{
components: ['collapsible'],
version: '0.3.0',
description: 'Add `Collapsible` component',
prs: ['29617'],
type: 'new',
},
{
components: ['textfield'],
version: '0.3.0',
description: 'Add `TextField` component instead of `Field` + `Input`',
prs: ['29364'],
type: 'new',
},
{
components: ['datatable'],
version: '0.3.0',
description: 'Add `TableCellProfile`',
prs: ['29600'],
type: 'new',
},
{
components: [],
version: '0.3.0',
description: 'Add breakpoint hooks - `up()` and `down()`',
prs: ['29564'],
type: 'new',
},
{
components: [],
version: '0.3.0',
description: 'Add gray scale css tokens',
prs: ['29543'],
type: 'new',
},
{
components: [],
version: '0.3.0',
description:
'Update CSS styling API using `[data-___]` instead of class names for props',
prs: ['29560'],
},
{
components: ['checkbox'],
version: '0.3.0',
description: 'Update `Checkbox` dark mode',
prs: ['29544'],
},
{
components: ['container'],
version: '0.3.0',
description: 'Update `Container` styles',
prs: ['29475'],
},
{
components: ['menu'],
version: '0.3.0',
description: 'Update `Menu` styles',
prs: ['29351'],
},
{
components: ['select'],
version: '0.3.0',
description: 'Fix `Select` styles on small sizes + with long option names',
prs: ['29545'],
},
{
components: ['link'],
version: '0.3.0',
description: 'Fix render prop on `Link`',
prs: ['29247'],
},
{
components: ['textfield', 'select'],
version: '0.3.0',
description: 'Remove `Field` from `TextField` + `Select`',
prs: ['29482'],
},
{
components: ['text', 'heading'],
version: '0.3.0',
description: 'Update `textDecoration` to `none` on `Text` / `Heading`',
prs: ['29357'],
},
{
components: ['text', 'heading'],
version: '0.3.0',
description: 'Update `textDecoration` to `none` on `Text` / `Heading`',
prs: ['29357'],
},
{
components: [],
version: '0.3.0',
description: 'Docs - Use stories from Storybook for all examples in Nextjs',
prs: ['29306'],
},
{
components: [],
version: '0.3.0',
description: 'Docs - Add release page (this one 🤗)',
prs: ['29461'],
},
{
components: [],
version: '0.3.0',
description: 'Docs - Add docs for Menu, Link',
prs: ['29576'],
},
{
components: [],
version: '0.3.0',
description: 'Fix CSS watch mode',
prs: ['29352'],
},
];
+12
View File
@@ -0,0 +1,12 @@
import type { ChangelogProps } from '../types';
export const changelog_0_3_2: ChangelogProps[] = [
{
components: [],
version: '0.3.2',
description: `Fix Canon missing dependencies`,
prs: ['29642'],
type: 'fix',
commitSha: 'e996368',
},
];
+87
View File
@@ -0,0 +1,87 @@
import type { ChangelogProps } from '../types';
export const changelog_0_4_0: ChangelogProps[] = [
{
components: ['tabs'],
version: '0.4.0',
description: 'New `Tabs` component',
prs: ['29996'],
type: 'new',
},
{
components: ['text', 'heading'],
version: '0.4.0',
description: 'Add `truncate` prop to `Text` and `Heading`',
prs: ['29988'],
type: 'new',
},
{
components: ['menu'],
version: '0.4.0',
description: 'Add combobox option to `Menu`',
prs: ['29986'],
type: 'new',
},
{
components: ['textfield'],
version: '0.4.0',
description: 'Add icon prop on `TextField`',
prs: ['29820'],
type: 'new',
},
{
components: ['button', 'button-icon'],
version: '0.4.0',
description: 'Improve icon props on `Button` and `IconButton`',
prs: ['29667'],
},
{
components: ['text', 'heading'],
version: '0.4.0',
description:
'Improve the way we treat custom render on `Text` and `Heading`',
prs: ['29989'],
},
{
components: ['menu'],
version: '0.4.0',
description: 'Improve `Menu` styles',
prs: ['29986'],
},
{
components: ['textfield'],
version: '0.4.0',
description: 'Improve `TextField` styles',
prs: ['29974'],
},
{
components: ['textfield'],
version: '0.4.0',
description: 'Improve clear button on `TextField`',
prs: ['29878'],
},
{
components: ['flex'],
version: '0.4.0',
description: 'Fix spacing props on all layout components',
prs: ['30013'],
},
{
components: [],
version: '0.4.0',
description: 'Fix - Pin Base UI version',
prs: ['29782'],
},
{
components: ['select'],
version: '0.4.0',
description: 'Fix - Clicking `Select` label moves focus to trigger',
prs: ['29755'],
},
{
components: ['datatable'],
version: '0.4.0',
description: 'Fix `DataTable.Pagination` count issue',
prs: ['29688'],
},
];
+86
View File
@@ -0,0 +1,86 @@
import type { ChangelogProps } from '../types';
export const changelog_0_5_0: ChangelogProps[] = [
{
components: ['textfield'],
version: '0.5.0',
description: '`TextField` now has multiple label sizes.',
prs: ['30249'],
type: 'breaking',
},
{
components: ['textfield'],
version: '0.5.0',
description:
'`TextField` can now hide label and description while keeping them available for screen readers.',
prs: ['30249'],
type: 'breaking',
},
{
components: ['textfield'],
version: '0.5.0',
description:
'We are removing the `render` prop in favour of the `as` prop on `Heading` and `Text`.',
prs: ['30291'],
type: 'breaking',
},
{
components: ['textfield'],
version: '0.5.0',
description: 'Move `TextField` component to use react Aria under the hood.',
prs: ['30286'],
type: 'breaking',
},
{
components: ['button', 'button-link'],
version: '0.5.0',
description:
'Added a render prop to the `Button` component to use it as a link.',
prs: ['30165'],
type: 'new',
},
{
components: ['heading'],
version: '0.5.0',
description: 'Fix styling for the title4 prop on the Heading component.',
prs: ['30167'],
type: 'fix',
},
{
components: ['flex'],
version: '0.5.0',
description:
'Add `min-width: 0;` by default on Flex components to support truncated text.',
prs: ['30168'],
type: 'fix',
},
{
components: ['button', 'button-link', 'button-icon'],
version: '0.5.0',
description:
'`Button`, `ButtonLink`, `ButtonIcon` now default to size `small` instead of `medium`',
prs: ['30085', '30097'],
type: 'breaking',
},
{
components: ['grid'],
version: '0.5.0',
description: 'Rename Grid component to `<Grid.Root />`',
prs: ['30013'],
type: 'breaking',
},
{
components: ['flex', 'container', 'grid', 'box'],
version: '0.5.0',
description: 'Fixes spacing props on layout components',
prs: ['30013'],
type: 'fix',
},
{
components: ['switch'],
version: '0.5.0',
description: 'New `Switch` component',
prs: ['30251'],
type: 'new',
},
];
+105
View File
@@ -0,0 +1,105 @@
import type { ChangelogProps } from '../types';
export const changelog_0_6_0: ChangelogProps[] = [
{
components: ['tooltip'],
version: '0.6.0',
description: 'New `Tooltip` component.',
prs: ['30461'],
type: 'new',
},
{
components: ['card'],
version: '0.6.0',
description: 'New `Card` component.',
prs: ['30467'],
type: 'new',
},
{
components: ['header'],
version: '0.6.0',
description: 'New `Header` component.',
prs: ['30410', '30459', '30493'],
type: 'new',
},
{
components: ['button', 'button-link', 'button-icon'],
version: '0.6.0',
description: 'Improve `Button`, `ButtonIcon` and `ButtonLink` styling.',
prs: ['30448'],
type: 'fix',
},
{
components: ['text', 'heading'],
version: '0.6.0',
description:
'Update return types for `Heading` & `Text` components for React 19.',
prs: ['30440'],
type: 'fix',
},
{
components: ['button', 'button-link', 'button-icon'],
version: '0.6.0',
description:
'New `tertiary` variant to `Button`, `ButtonIcon` and `ButtonLink`.',
prs: ['30453'],
type: 'new',
},
{
components: ['skeleton'],
version: '0.6.0',
description: 'New `Skeleton` component.',
prs: ['30466'],
type: 'new',
},
{
components: ['button-icon'],
version: '0.6.0',
description: 'Rename `IconButton` to `ButtonIcon`.',
prs: ['30297'],
type: 'breaking',
},
{
components: ['button-link'],
version: '0.6.0',
description:
'New `ButtonLink`, which replaces the previous render prop pattern on `Button` and `IconButton`.',
prs: ['30297'],
type: 'new',
},
{
components: ['button', 'button-link', 'button-icon'],
version: '0.6.0',
description: 'Remove the `render` prop from all button-related components.',
prs: ['30297'],
type: 'breaking',
},
{
components: [],
version: '0.6.0',
description: 'We are consolidating all css files into a single styles.css.',
prs: ['30325'],
type: 'fix',
},
{
components: ['searchfield'],
version: '0.6.0',
description: 'New `SearchField` component.',
prs: ['30357'],
type: 'new',
},
{
components: ['radio-group'],
version: '0.6.0',
description: 'New `RadioGroup` + `Radio` component.',
prs: ['30327'],
type: 'new',
},
{
components: ['textfield'],
version: '0.6.0',
description: 'Added placeholder prop back to `TextField` component.',
prs: ['30286'],
type: 'fix',
},
];
+212
View File
@@ -0,0 +1,212 @@
import type { ChangelogProps } from '../types';
export const changelog_0_7_0: ChangelogProps[] = [
{
components: ['datatable', 'table'],
version: '0.7.0',
description: `We are moving our DataTable component to React Aria. We removed our DataTable to only use Table as a single and opinionated option for tables. This new structure is made possible by using React Aria under the hood.`,
prs: ['30654'],
type: 'breaking',
commitSha: '0615e54',
},
{
components: ['header-page'],
version: '0.7.0',
description: `Backstage UI - HeaderPage - We are updating the breadcrumb to be more visible and accessible.`,
prs: ['30874'],
type: 'breaking',
commitSha: 'b245c9d',
},
{
components: ['menu'],
version: '0.7.0',
description: `**Breaking change** We are updating the Menu component to use React Aria under the hood. The structure and all props are changing to follow React Aria's guidance.`,
prs: ['30908'],
type: 'breaking',
commitSha: '800f593',
},
{
components: ['text', 'heading', 'link'],
version: '0.7.0',
description: `**Breaking** We are upgrading our \`Text\` component to support all font sizes making the \`Heading\` component redundant. The new \`Text\` component introduces 4 sizes for title and 4 sizes for body text. All of these work in multiple colors and font weights. We improved the \`as\` prop to include all possible values. The \`Link\` component has also been updated to match the new \`Text\` component.`,
prs: ['30592'],
type: 'breaking',
commitSha: 'b0e47f3',
},
{
components: ['select'],
version: '0.7.0',
description: `Fixes some styles on the Select component in BUI.`,
prs: ['30642'],
type: 'fix',
commitSha: 'de89a3d',
},
{
components: ['card'],
version: '0.7.0',
description: `Export CardHeader, CardBody and CardFooter from Card component index`,
prs: ['30882'],
type: 'fix',
commitSha: 'a251b3e',
},
{
components: ['tag-group'],
version: '0.7.0',
description: `Add new TagGroup component to Backstage UI.`,
prs: ['30919'],
type: 'new',
commitSha: 'f761306',
},
{
components: ['header', 'header-page'],
version: '0.7.0',
description: `Fixes a couple of small bugs in BUI including setting H1 and H2 correctly on the Header and HeaderPage.`,
prs: ['30636'],
type: 'fix',
commitSha: '75fead9',
},
{
components: ['tooltip'],
version: '0.7.0',
description: `Update styling of Tooltip element`,
prs: ['30591'],
type: 'fix',
commitSha: 'e7ff178',
},
{
components: ['header-page', 'header'],
version: '0.7.0',
description: `**Breaking change** Move breadcrumb to fit in the \`HeaderPage\` instead of the \`Header\` in Backstage UI.`,
prs: ['30701'],
type: 'fix',
commitSha: '230b410',
},
{
components: [],
version: '0.7.0',
description: `We are motion away from \`motion\` to use \`gsap\` instead to make Backstage UI backward compatible with React 17.`,
prs: ['30626'],
type: 'fix',
commitSha: '2f9a084',
},
{
components: ['menu'],
version: '0.7.0',
description: `Updated Menu component in Backstage UI to use useId() from React Aria instead of React to support React 17.`,
prs: ['30675'],
type: 'fix',
commitSha: 'd4e603e',
},
{
components: ['select'],
version: '0.7.0',
description: `Remove stylesheet import from Select component.`,
prs: ['30800'],
type: 'fix',
commitSha: '8bdc491',
},
{
components: ['searchfield'],
version: '0.7.0',
description: `Add \`startCollapsed\` prop on the \`SearchField\` component in BUI.`,
prs: ['30729'],
type: 'new',
commitSha: '404b426',
},
{
components: ['header'],
version: '0.7.0',
description: `Adds onTabSelectionChange to ui header component.`,
prs: ['30588'],
type: 'fix',
commitSha: 'e0e886f',
},
{
components: ['datatable', 'table'],
version: '0.7.0',
description: `We are moving our DataTable component to React Aria. We removed our DataTable to only use Table as a single and opinionated option for tables. This new structure is made possible by using React Aria under the hood.`,
prs: ['30654'],
type: 'breaking',
commitSha: '0615e54',
},
{
components: ['header-page', 'header'],
version: '0.7.0',
description: `**Breaking change** Move breadcrumb to fit in the \`HeaderPage\` instead of the \`Header\` in Backstage UI.`,
prs: ['30701'],
type: 'fix',
commitSha: '230b410',
},
{
components: ['select'],
version: '0.7.0',
description: `Remove stylesheet import from Select component.`,
prs: ['30800'],
type: 'fix',
commitSha: '8bdc491',
},
{
components: ['searchfield'],
version: '0.7.0',
description: `Add \`startCollapsed\` prop on the \`SearchField\` component in BUI.`,
prs: ['30729'],
type: 'new',
commitSha: '404b426',
},
{
components: ['menu'],
version: '0.7.0',
description: `Updated Menu component in Backstage UI to use useId() from React Aria instead of React to support React 17.`,
prs: ['30675'],
type: 'fix',
commitSha: 'd4e603e',
},
{
components: ['select'],
version: '0.7.0',
description: `Fixes some styles on the Select component in BUI.`,
prs: ['30642'],
type: 'fix',
commitSha: 'de89a3d',
},
{
components: ['header', 'header-page'],
version: '0.7.0',
description: `Fixes a couple of small bugs in BUI including setting H1 and H2 correctly on the Header and HeaderPage.`,
prs: ['30636'],
type: 'fix',
commitSha: '75fead9',
},
{
components: [],
version: '0.7.0',
description: `We are motion away from \`motion\` to use \`gsap\` instead to make Backstage UI backward compatible with React 17.`,
prs: ['30626'],
type: 'fix',
commitSha: '2f9a084',
},
{
components: ['text', 'heading', 'link'],
version: '0.7.0',
description: `**Breaking** We are upgrading our \`Text\` component to support all font sizes making the \`Heading\` component redundant. The new \`Text\` component introduces 4 sizes for title and 4 sizes for body text. All of these work in multiple colors and font weights. We improved the \`as\` prop to include all possible values. The \`Link\` component has also been updated to match the new \`Text\` component.`,
prs: ['30592'],
type: 'breaking',
commitSha: 'b0e47f3',
},
{
components: ['tooltip'],
version: '0.7.0',
description: `Update styling of Tooltip element`,
prs: ['30591'],
type: 'fix',
commitSha: 'e7ff178',
},
{
components: ['header'],
version: '0.7.0',
description: `Adds onTabSelectionChange to ui header component.`,
prs: ['30588'],
type: 'fix',
commitSha: 'e0e886f',
},
];
+44
View File
@@ -0,0 +1,44 @@
import type { ChangelogProps } from '../types';
export const changelog_0_7_1: ChangelogProps[] = [
{
components: ['flex'],
version: '0.7.1',
description: `Add missing class for flex: baseline`,
prs: ['31013'],
type: 'new',
commitSha: '7307930',
},
{
components: ['select'],
version: '0.7.1',
description: `Fix Select component to properly attach aria-label and aria-labelledby props to the rendered element for improved accessibility.`,
prs: ['31037'],
type: 'fix',
commitSha: '89da341',
},
{
components: [],
version: '0.7.1',
description: `Removed the need to mock \`window.matchMedia\` in tests, falling back to default breakpoint values instead.`,
prs: ['31148'],
type: 'fix',
commitSha: '0ffa4c7',
},
{
components: ['flex'],
version: '0.7.1',
description: `Add missing class for flex: baseline`,
prs: ['31013'],
type: 'new',
commitSha: '7307930',
},
{
components: ['select'],
version: '0.7.1',
description: `Fix Select component to properly attach aria-label and aria-labelledby props to the rendered element for improved accessibility.`,
prs: ['31037'],
type: 'fix',
commitSha: '89da341',
},
];
+68
View File
@@ -0,0 +1,68 @@
import type { ChangelogProps } from '../types';
export const changelog_0_7_2: ChangelogProps[] = [
{
components: ['tabs', 'header'],
version: '0.7.2',
description: `Making href mandatory in tabs that are part of a Header component`,
prs: ['31343'],
type: 'fix',
commitSha: '3c921c5',
},
{
components: ['button-link'],
version: '0.7.2',
description: `Add react router for internal routing for ButtonLinks`,
prs: ['31276'],
type: 'new',
commitSha: '5c21e45',
},
{
components: ['tabs'],
version: '0.7.2',
description: `Remove auto selection of tabs for tabs that all have href defined`,
prs: ['31281'],
type: 'fix',
commitSha: '9781815',
},
{
components: ['menu'],
version: '0.7.2',
description: `Using react router for internal links in the Menu component`,
prs: ['31339'],
type: 'fix',
commitSha: 'f6dff5b',
},
{
components: ['button', 'tooltip'],
version: '0.7.2',
description: `Enable tooltips on disabled buttons with automatic wrapper`,
prs: ['31230'],
type: 'fix',
commitSha: 'a9b88be',
},
{
components: [],
version: '0.7.2',
description: `Avoid overriding onChange when spreading props`,
prs: ['31232'],
type: 'fix',
commitSha: '4adbb03',
},
{
components: ['tabs'],
version: '0.7.2',
description: `remove default selection of tab`,
prs: ['31216'],
type: 'fix',
commitSha: '827340f',
},
{
components: ['searchfield', 'header'],
version: '0.7.2',
description: `Improved SearchField component flex layout and animations. Fixed SearchField behavior in Header components by switching from width-based transitions to flex-basis transitions for better responsive behavior. Added new Storybook stories to test SearchField integration with Header component.`,
prs: ['31158'],
type: 'fix',
commitSha: '9a47125',
},
];
+172
View File
@@ -0,0 +1,172 @@
import type { ChangelogProps } from '../types';
export const changelog_0_8_0: ChangelogProps[] = [
{
components: ['password-field', 'textfield'],
version: '0.8.0',
description: `**BREAKING**: Added a new \`PasswordField\` component. As part of this change, the \`password\` and \`search\` types have been removed from \`TextField\`.`,
prs: ['31238'],
type: 'breaking',
commitSha: '9acc1d6',
},
{
components: [],
version: '0.8.0',
description: `**BREAKING** Restructure Backstage UI component styling to use CSS Modules instead of pure CSS. We don't expect this to be an issue in practice but it is important to call out that all styles are now loaded through CSS modules with generated class names. We are still providing fixed class names for all components to allow anyone to style their Backstage instance.`,
prs: ['31399'],
type: 'breaking',
commitSha: 'b0d11b5',
},
{
components: ['scrollarea'],
version: '0.8.0',
description: `**BREAKING** The ScrollArea component has been removed from Backstage UI because it did not meet our accessibility standards.`,
prs: ['31409'],
type: 'breaking',
commitSha: '0c53517',
},
{
components: ['icon'],
version: '0.8.0',
description: `**BREAKING** Remove Icon component in Backstage UI. This component was creating issue for tree-shaking. It is recommended to use icons from @remixicon/react until we found a better alternative in Backstage UI.`,
prs: ['31407'],
type: 'breaking',
commitSha: '7b319c5',
},
{
components: ['dialog'],
version: '0.8.0',
description: `Adding a new Dialog component to Backstage UI.`,
prs: ['31371'],
type: 'fix',
commitSha: '2591b42',
},
{
components: ['tabs'],
version: '0.8.0',
description: `remove default selection of tab`,
prs: ['31216'],
type: 'fix',
commitSha: '827340f',
},
{
components: [],
version: '0.8.0',
description: `Fix margin utility classes in Backstage UI.`,
prs: ['31389'],
type: 'fix',
commitSha: '5dc17cc',
},
{
components: ['menu'],
version: '0.8.0',
description: `Fix scroll jumping when opening menu in Backstage UI.`,
prs: ['31394'],
type: 'fix',
commitSha: '85faee0',
},
{
components: ['tabs', 'header'],
version: '0.8.0',
description: `Making href mandatory in tabs that are part of a Header component`,
prs: ['31343'],
type: 'fix',
commitSha: '3c921c5',
},
{
components: [],
version: '0.8.0',
description: `Update react-aria-components to version 1.13.0`,
prs: ['31367'],
type: 'fix',
commitSha: 'df7d2cf',
},
{
components: ['table'],
version: '0.8.0',
description: `Fix table sorting icon position in Backstage UI.`,
prs: ['31393'],
type: 'fix',
commitSha: '507ee55',
},
{
components: ['menu'],
version: '0.8.0',
description: `Add new \`virtualized\`, \`maxWidth\` and \`maxHeight\` props to \`Menu\`, \`MenuListBox\`, \`MenuAutocomplete\` and \`MenuAutocompleteListBox\` to allow for virtalization of long lists inside menus.`,
prs: ['31375'],
type: 'new',
commitSha: '8b7c3c9',
},
{
components: ['box', 'container', 'flex', 'grid'],
version: '0.8.0',
description: `Added support for data attributes in \`<Box />\`, \`<Container />\`, \`<Flex />\`, and \`<Grid />\` components, ensuring they are correctly applied to the rendered elements.`,
prs: ['31374'],
type: 'new',
commitSha: 'b940062',
},
{
components: ['scrollarea', 'card'],
version: '0.8.0',
description: `Cleaning up Backstage UI props definitions as well as removing ScrollArea in Card to improve accessibility.`,
prs: ['31404'],
type: 'fix',
commitSha: '206c801',
},
{
components: ['button-link'],
version: '0.8.0',
description: `Add react router for internal routing for ButtonLinks`,
prs: ['31276'],
type: 'new',
commitSha: '5c21e45',
},
{
components: [],
version: '0.8.0',
description: `Added a background color default on the body`,
prs: ['31365'],
type: 'new',
commitSha: '865bce8',
},
{
components: [],
version: '0.8.0',
description: `We are restructuring our CSS to have a better layer structure.`,
prs: ['31362'],
type: 'fix',
commitSha: 'af4d9b4',
},
{
components: ['searchfield', 'header'],
version: '0.8.0',
description: `Improved SearchField component flex layout and animations. Fixed SearchField behavior in Header components by switching from width-based transitions to flex-basis transitions for better responsive behavior. Added new Storybook stories to test SearchField integration with Header component.`,
prs: ['31158'],
type: 'fix',
commitSha: '9a47125',
},
{
components: ['tabs'],
version: '0.8.0',
description: `Remove auto selection of tabs for tabs that all have href defined`,
prs: ['31281'],
type: 'fix',
commitSha: '9781815',
},
{
components: [],
version: '0.8.0',
description: `Avoid overriding onChange when spreading props`,
prs: ['31232'],
type: 'fix',
commitSha: '4adbb03',
},
{
components: ['menu'],
version: '0.8.0',
description: `Using react router for internal links in the Menu component`,
prs: ['31339'],
type: 'fix',
commitSha: 'f6dff5b',
},
];
+44
View File
@@ -0,0 +1,44 @@
import type { ChangelogProps } from '../types';
export const changelog_0_8_2: ChangelogProps[] = [
{
components: ['text'],
version: '0.8.2',
description: `Fix default text color in Backstage UI`,
prs: ['31429'],
type: 'fix',
commitSha: '26c6a78',
},
{
components: ['text'],
version: '0.8.2',
description: `Fix the default font size in Backstage UI.`,
prs: ['31435'],
type: 'fix',
commitSha: 'dac851f',
},
{
components: [],
version: '0.8.2',
description: `Fix CSS layer ordering in Backstage UI to make sure component styles are loaded after tokens and base declarations.`,
prs: ['31448'],
type: 'fix',
commitSha: '3c0ea67',
},
{
components: [],
version: '0.8.2',
description: `Fix font smoothing as default in Backstage UI.`,
prs: ['31444'],
type: 'fix',
commitSha: '4eb455c',
},
{
components: ['text'],
version: '0.8.2',
description: `Fix default font wight and font family in Backstage UI.`,
prs: ['31432'],
type: 'fix',
commitSha: '00bfb83',
},
];

Some files were not shown because too many files have changed in this diff Show More