Merge branch 'master' of https://github.com/backstage/backstage into feat/oauth-dialog-custom-message
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Fixed an issue causing TechDocs to not properly handle initial redirect.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-graph': patch
|
||||
---
|
||||
|
||||
Catalog graph plugin support i18n
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Bumped create-app version.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
We are consolidating all css files into a single styles.css in Canon.
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': major
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
**BREAKING:** The experimental `catalog.useUrlReadersSearch` configuration flag (introduced in v1.36) has been removed.
|
||||
|
||||
The `UrlReaderProcessor` now always uses the `search` method of `UrlReaders`. Built-in `UrlReaderService` implementations have been updated accordingly.
|
||||
If you use custom `UrlReaderService` implementations, you need to adapt their `search` method to correctly handle both specific URLs and potential
|
||||
search patterns (see changes on built-in readers [in the original PR](https://github.com/backstage/backstage/pull/28379/files#diff-68b0452f173ee54bdd40f7b5e047a9cb8bb59200425622c212c217b76dac1d1b)).
|
||||
|
||||
Previous behavior was to call the `search` method only if the parsed Git URL's filename contained a wildcard and use `readUrl` otherwise. Each `UrlReaderService` must implement this logic in the `search` method instead.
|
||||
|
||||
This allows each `UrlReaderService` implementation to check whether it's a search URL (that contains a wildcard pattern) or not using logic that is specific to each provider.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Add new SearchField component in Canon
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/config-loader': patch
|
||||
'@backstage/config': patch
|
||||
---
|
||||
|
||||
Loosen the requirements for a key to be considered valid config.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Add new Header component to Canon.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
|
||||
'@backstage/plugin-search-backend-module-elasticsearch': patch
|
||||
'@backstage/backend-dynamic-feature-service': patch
|
||||
'@backstage/plugin-catalog-backend-module-puppetdb': patch
|
||||
'@backstage/plugin-catalog-backend-module-msgraph': patch
|
||||
'@backstage/plugin-catalog-backend-module-ldap': patch
|
||||
'@backstage/frontend-app-api': patch
|
||||
'@backstage/plugin-permission-common': patch
|
||||
'@backstage/plugin-kubernetes-node': patch
|
||||
'@backstage/plugin-permission-node': patch
|
||||
'@backstage/catalog-model': patch
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
'@backstage/config': patch
|
||||
---
|
||||
|
||||
Just some more circular dep cleanup
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Filter MultiEntityPicker options based on rendered option value
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Add new `RadioGroup` + `Radio` component to Canon
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
|
||||
---
|
||||
|
||||
Fixed bug in `IncrementalIngestionEngine` by adding `burstLength` check when a burst completes
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'yarn-plugin-backstage': patch
|
||||
---
|
||||
|
||||
Fixed a bug that would prevent the yarn plugin from installing new dependencies with the `backstage:^` protocol.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
'@backstage/backend-test-utils': minor
|
||||
---
|
||||
|
||||
Add a standard `toString` on credentials objects
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/repo-tools': patch
|
||||
---
|
||||
|
||||
Fix an issue where errors were not printed to console when running `backstage-repo-tools schema openapi generate` without the `--watch` flag.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/repo-tools': minor
|
||||
---
|
||||
|
||||
Clear output directory before running `package-docs` and skip all internal packages.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-dynamic-feature-service': patch
|
||||
---
|
||||
|
||||
Fix wrong imports which lead to module initialization failures when enabling dynamic plugins.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-node-test-utils': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/plugin-scaffolder-node': patch
|
||||
---
|
||||
|
||||
An internal refactor which adds additional types to experimental checkpoints
|
||||
+207
-172
@@ -2,204 +2,239 @@
|
||||
"mode": "pre",
|
||||
"tag": "next",
|
||||
"initialVersions": {
|
||||
"example-app": "0.2.109",
|
||||
"@backstage/app-defaults": "1.6.2",
|
||||
"example-app-next": "0.0.23",
|
||||
"app-next-example-plugin": "0.0.23",
|
||||
"example-backend": "0.0.38",
|
||||
"@backstage/backend-app-api": "1.2.3",
|
||||
"@backstage/backend-defaults": "0.10.0",
|
||||
"example-app": "0.2.110",
|
||||
"@backstage/app-defaults": "1.6.3",
|
||||
"example-app-next": "0.0.24",
|
||||
"app-next-example-plugin": "0.0.24",
|
||||
"example-backend": "0.0.39",
|
||||
"@backstage/backend-app-api": "1.2.4",
|
||||
"@backstage/backend-defaults": "0.11.0",
|
||||
"@backstage/backend-dev-utils": "0.1.5",
|
||||
"@backstage/backend-dynamic-feature-service": "0.7.0",
|
||||
"@backstage/backend-openapi-utils": "0.5.3",
|
||||
"@backstage/backend-plugin-api": "1.3.1",
|
||||
"@backstage/backend-test-utils": "1.5.0",
|
||||
"@backstage/canon": "0.4.0",
|
||||
"@backstage/catalog-client": "1.10.0",
|
||||
"@backstage/backend-dynamic-feature-service": "0.7.1",
|
||||
"@backstage/backend-openapi-utils": "0.5.4",
|
||||
"@backstage/backend-plugin-api": "1.4.0",
|
||||
"@backstage/backend-test-utils": "1.6.0",
|
||||
"@backstage/canon": "0.5.0",
|
||||
"@backstage/catalog-client": "1.10.1",
|
||||
"@backstage/catalog-model": "1.7.4",
|
||||
"@backstage/cli": "0.32.1",
|
||||
"@backstage/cli": "0.33.0",
|
||||
"@backstage/cli-common": "0.1.15",
|
||||
"@backstage/cli-node": "0.2.13",
|
||||
"@backstage/codemods": "0.1.52",
|
||||
"@backstage/config": "1.3.2",
|
||||
"@backstage/config-loader": "1.10.1",
|
||||
"@backstage/core-app-api": "1.17.0",
|
||||
"@backstage/core-compat-api": "0.4.2",
|
||||
"@backstage/core-components": "0.17.2",
|
||||
"@backstage/core-plugin-api": "1.10.7",
|
||||
"@backstage/create-app": "0.6.2",
|
||||
"@backstage/dev-utils": "1.1.10",
|
||||
"e2e-test": "0.2.28",
|
||||
"@backstage/core-app-api": "1.17.1",
|
||||
"@backstage/core-compat-api": "0.4.3",
|
||||
"@backstage/core-components": "0.17.3",
|
||||
"@backstage/core-plugin-api": "1.10.8",
|
||||
"@backstage/create-app": "0.7.0",
|
||||
"@backstage/dev-utils": "1.1.11",
|
||||
"e2e-test": "0.2.29",
|
||||
"@backstage/e2e-test-utils": "0.1.1",
|
||||
"@backstage/errors": "1.2.7",
|
||||
"@backstage/eslint-plugin": "0.1.10",
|
||||
"@backstage/frontend-app-api": "0.11.2",
|
||||
"@backstage/frontend-defaults": "0.2.2",
|
||||
"@backstage/frontend-dynamic-feature-loader": "0.1.1",
|
||||
"@internal/frontend": "0.0.9",
|
||||
"@backstage/frontend-plugin-api": "0.10.2",
|
||||
"@backstage/frontend-test-utils": "0.3.2",
|
||||
"@backstage/eslint-plugin": "0.1.11",
|
||||
"@backstage/frontend-app-api": "0.11.3",
|
||||
"@backstage/frontend-defaults": "0.2.3",
|
||||
"@backstage/frontend-dynamic-feature-loader": "0.1.2",
|
||||
"@internal/frontend": "0.0.10",
|
||||
"@backstage/frontend-plugin-api": "0.10.3",
|
||||
"@backstage/frontend-test-utils": "0.3.3",
|
||||
"@backstage/integration": "1.17.0",
|
||||
"@backstage/integration-aws-node": "0.1.16",
|
||||
"@backstage/integration-react": "1.2.7",
|
||||
"@backstage/integration-react": "1.2.8",
|
||||
"@internal/opaque": "0.0.1",
|
||||
"@backstage/release-manifests": "0.0.13",
|
||||
"@backstage/repo-tools": "0.13.3",
|
||||
"@internal/scaffolder": "0.0.9",
|
||||
"@techdocs/cli": "1.9.3",
|
||||
"techdocs-cli-embedded-app": "0.2.108",
|
||||
"@backstage/test-utils": "1.7.8",
|
||||
"@backstage/repo-tools": "0.14.0",
|
||||
"@internal/scaffolder": "0.0.10",
|
||||
"@techdocs/cli": "1.9.4",
|
||||
"techdocs-cli-embedded-app": "0.2.109",
|
||||
"@backstage/test-utils": "1.7.9",
|
||||
"@backstage/theme": "0.6.6",
|
||||
"@backstage/types": "1.2.1",
|
||||
"@backstage/version-bridge": "1.0.11",
|
||||
"yarn-plugin-backstage": "0.0.5",
|
||||
"@backstage/plugin-api-docs": "0.12.7",
|
||||
"yarn-plugin-backstage": "0.0.6",
|
||||
"@backstage/plugin-api-docs": "0.12.8",
|
||||
"@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.10",
|
||||
"@backstage/plugin-app": "0.1.9",
|
||||
"@backstage/plugin-app-backend": "0.5.2",
|
||||
"@backstage/plugin-app-node": "0.1.33",
|
||||
"@backstage/plugin-app-visualizer": "0.1.19",
|
||||
"@backstage/plugin-auth-backend": "0.25.0",
|
||||
"@backstage/plugin-auth-backend-module-atlassian-provider": "0.4.3",
|
||||
"@backstage/plugin-auth-backend-module-auth0-provider": "0.2.3",
|
||||
"@backstage/plugin-auth-backend-module-aws-alb-provider": "0.4.3",
|
||||
"@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.2.8",
|
||||
"@backstage/plugin-auth-backend-module-bitbucket-provider": "0.3.3",
|
||||
"@backstage/plugin-auth-backend-module-bitbucket-server-provider": "0.2.3",
|
||||
"@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.4.3",
|
||||
"@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.4.3",
|
||||
"@backstage/plugin-auth-backend-module-github-provider": "0.3.3",
|
||||
"@backstage/plugin-auth-backend-module-gitlab-provider": "0.3.3",
|
||||
"@backstage/plugin-auth-backend-module-google-provider": "0.3.3",
|
||||
"@backstage/plugin-auth-backend-module-guest-provider": "0.2.8",
|
||||
"@backstage/plugin-auth-backend-module-microsoft-provider": "0.3.3",
|
||||
"@backstage/plugin-auth-backend-module-oauth2-provider": "0.4.3",
|
||||
"@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.2.8",
|
||||
"@backstage/plugin-auth-backend-module-oidc-provider": "0.4.3",
|
||||
"@backstage/plugin-auth-backend-module-okta-provider": "0.2.3",
|
||||
"@backstage/plugin-auth-backend-module-onelogin-provider": "0.3.3",
|
||||
"@backstage/plugin-auth-backend-module-pinniped-provider": "0.3.3",
|
||||
"@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.5.3",
|
||||
"@backstage/plugin-auth-node": "0.6.3",
|
||||
"@backstage/plugin-auth-react": "0.1.15",
|
||||
"@backstage/plugin-app": "0.1.10",
|
||||
"@backstage/plugin-app-backend": "0.5.3",
|
||||
"@backstage/plugin-app-node": "0.1.34",
|
||||
"@backstage/plugin-app-visualizer": "0.1.20",
|
||||
"@backstage/plugin-auth-backend": "0.25.1",
|
||||
"@backstage/plugin-auth-backend-module-atlassian-provider": "0.4.4",
|
||||
"@backstage/plugin-auth-backend-module-auth0-provider": "0.2.4",
|
||||
"@backstage/plugin-auth-backend-module-aws-alb-provider": "0.4.4",
|
||||
"@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.2.9",
|
||||
"@backstage/plugin-auth-backend-module-bitbucket-provider": "0.3.4",
|
||||
"@backstage/plugin-auth-backend-module-bitbucket-server-provider": "0.2.4",
|
||||
"@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.4.4",
|
||||
"@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.4.4",
|
||||
"@backstage/plugin-auth-backend-module-github-provider": "0.3.4",
|
||||
"@backstage/plugin-auth-backend-module-gitlab-provider": "0.3.4",
|
||||
"@backstage/plugin-auth-backend-module-google-provider": "0.3.4",
|
||||
"@backstage/plugin-auth-backend-module-guest-provider": "0.2.9",
|
||||
"@backstage/plugin-auth-backend-module-microsoft-provider": "0.3.4",
|
||||
"@backstage/plugin-auth-backend-module-oauth2-provider": "0.4.4",
|
||||
"@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.2.9",
|
||||
"@backstage/plugin-auth-backend-module-oidc-provider": "0.4.4",
|
||||
"@backstage/plugin-auth-backend-module-okta-provider": "0.2.4",
|
||||
"@backstage/plugin-auth-backend-module-onelogin-provider": "0.3.4",
|
||||
"@backstage/plugin-auth-backend-module-pinniped-provider": "0.3.4",
|
||||
"@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.5.4",
|
||||
"@backstage/plugin-auth-node": "0.6.4",
|
||||
"@backstage/plugin-auth-react": "0.1.16",
|
||||
"@backstage/plugin-bitbucket-cloud-common": "0.3.0",
|
||||
"@backstage/plugin-catalog": "1.30.0",
|
||||
"@backstage/plugin-catalog-backend": "2.0.0",
|
||||
"@backstage/plugin-catalog-backend-module-aws": "0.4.11",
|
||||
"@backstage/plugin-catalog-backend-module-azure": "0.3.5",
|
||||
"@backstage/plugin-catalog-backend-module-backstage-openapi": "0.5.2",
|
||||
"@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.4.8",
|
||||
"@backstage/plugin-catalog-backend-module-bitbucket-server": "0.4.1",
|
||||
"@backstage/plugin-catalog-backend-module-gcp": "0.3.8",
|
||||
"@backstage/plugin-catalog-backend-module-gerrit": "0.3.2",
|
||||
"@backstage/plugin-catalog-backend-module-gitea": "0.1.0",
|
||||
"@backstage/plugin-catalog-backend-module-github": "0.9.0",
|
||||
"@backstage/plugin-catalog-backend-module-github-org": "0.3.10",
|
||||
"@backstage/plugin-catalog-backend-module-gitlab": "0.6.6",
|
||||
"@backstage/plugin-catalog-backend-module-gitlab-org": "0.2.9",
|
||||
"@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.7.0",
|
||||
"@backstage/plugin-catalog-backend-module-ldap": "0.11.5",
|
||||
"@backstage/plugin-catalog-backend-module-logs": "0.1.10",
|
||||
"@backstage/plugin-catalog-backend-module-msgraph": "0.7.0",
|
||||
"@backstage/plugin-catalog-backend-module-openapi": "0.2.10",
|
||||
"@backstage/plugin-catalog-backend-module-puppetdb": "0.2.10",
|
||||
"@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.8",
|
||||
"@backstage/plugin-catalog-backend-module-unprocessed": "0.6.0",
|
||||
"@backstage/plugin-catalog": "1.31.0",
|
||||
"@backstage/plugin-catalog-backend": "2.1.0",
|
||||
"@backstage/plugin-catalog-backend-module-aws": "0.4.12",
|
||||
"@backstage/plugin-catalog-backend-module-azure": "0.3.6",
|
||||
"@backstage/plugin-catalog-backend-module-backstage-openapi": "0.5.3",
|
||||
"@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.5.0",
|
||||
"@backstage/plugin-catalog-backend-module-bitbucket-server": "0.5.0",
|
||||
"@backstage/plugin-catalog-backend-module-gcp": "0.3.9",
|
||||
"@backstage/plugin-catalog-backend-module-gerrit": "0.3.3",
|
||||
"@backstage/plugin-catalog-backend-module-gitea": "0.1.1",
|
||||
"@backstage/plugin-catalog-backend-module-github": "0.10.0",
|
||||
"@backstage/plugin-catalog-backend-module-github-org": "0.3.11",
|
||||
"@backstage/plugin-catalog-backend-module-gitlab": "0.7.0",
|
||||
"@backstage/plugin-catalog-backend-module-gitlab-org": "0.2.10",
|
||||
"@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.7.1",
|
||||
"@backstage/plugin-catalog-backend-module-ldap": "0.11.6",
|
||||
"@backstage/plugin-catalog-backend-module-logs": "0.1.11",
|
||||
"@backstage/plugin-catalog-backend-module-msgraph": "0.7.1",
|
||||
"@backstage/plugin-catalog-backend-module-openapi": "0.2.11",
|
||||
"@backstage/plugin-catalog-backend-module-puppetdb": "0.2.11",
|
||||
"@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.9",
|
||||
"@backstage/plugin-catalog-backend-module-unprocessed": "0.6.1",
|
||||
"@backstage/plugin-catalog-common": "1.1.4",
|
||||
"@backstage/plugin-catalog-graph": "0.4.19",
|
||||
"@backstage/plugin-catalog-import": "0.13.0",
|
||||
"@backstage/plugin-catalog-node": "1.17.0",
|
||||
"@backstage/plugin-catalog-react": "1.18.0",
|
||||
"@backstage/plugin-catalog-unprocessed-entities": "0.2.17",
|
||||
"@backstage/plugin-catalog-graph": "0.4.20",
|
||||
"@backstage/plugin-catalog-import": "0.13.1",
|
||||
"@backstage/plugin-catalog-node": "1.17.1",
|
||||
"@backstage/plugin-catalog-react": "1.19.0",
|
||||
"@backstage/plugin-catalog-unprocessed-entities": "0.2.18",
|
||||
"@backstage/plugin-catalog-unprocessed-entities-common": "0.0.8",
|
||||
"@backstage/plugin-config-schema": "0.1.68",
|
||||
"@backstage/plugin-devtools": "0.1.27",
|
||||
"@backstage/plugin-devtools-backend": "0.5.5",
|
||||
"@backstage/plugin-config-schema": "0.1.69",
|
||||
"@backstage/plugin-devtools": "0.1.28",
|
||||
"@backstage/plugin-devtools-backend": "0.5.6",
|
||||
"@backstage/plugin-devtools-common": "0.1.16",
|
||||
"@backstage/plugin-events-backend": "0.5.2",
|
||||
"@backstage/plugin-events-backend-module-aws-sqs": "0.4.11",
|
||||
"@backstage/plugin-events-backend-module-azure": "0.2.20",
|
||||
"@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.20",
|
||||
"@backstage/plugin-events-backend-module-bitbucket-server": "0.1.1",
|
||||
"@backstage/plugin-events-backend-module-gerrit": "0.2.20",
|
||||
"@backstage/plugin-events-backend-module-github": "0.4.0",
|
||||
"@backstage/plugin-events-backend-module-gitlab": "0.3.1",
|
||||
"@backstage/plugin-events-backend-module-google-pubsub": "0.1.0",
|
||||
"@backstage/plugin-events-backend-test-utils": "0.1.44",
|
||||
"@backstage/plugin-events-node": "0.4.11",
|
||||
"@internal/plugin-todo-list": "1.0.39",
|
||||
"@internal/plugin-todo-list-backend": "1.0.39",
|
||||
"@backstage/plugin-events-backend": "0.5.3",
|
||||
"@backstage/plugin-events-backend-module-aws-sqs": "0.4.12",
|
||||
"@backstage/plugin-events-backend-module-azure": "0.2.21",
|
||||
"@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.21",
|
||||
"@backstage/plugin-events-backend-module-bitbucket-server": "0.1.2",
|
||||
"@backstage/plugin-events-backend-module-gerrit": "0.2.21",
|
||||
"@backstage/plugin-events-backend-module-github": "0.4.1",
|
||||
"@backstage/plugin-events-backend-module-gitlab": "0.3.2",
|
||||
"@backstage/plugin-events-backend-module-google-pubsub": "0.1.1",
|
||||
"@backstage/plugin-events-backend-module-kafka": "0.1.0",
|
||||
"@backstage/plugin-events-backend-test-utils": "0.1.45",
|
||||
"@backstage/plugin-events-node": "0.4.12",
|
||||
"@internal/plugin-todo-list": "1.0.40",
|
||||
"@internal/plugin-todo-list-backend": "1.0.40",
|
||||
"@internal/plugin-todo-list-common": "1.0.25",
|
||||
"@backstage/plugin-gateway-backend": "1.0.1",
|
||||
"@backstage/plugin-home": "0.8.8",
|
||||
"@backstage/plugin-home-react": "0.1.26",
|
||||
"@backstage/plugin-kubernetes": "0.12.7",
|
||||
"@backstage/plugin-kubernetes-backend": "0.19.6",
|
||||
"@backstage/plugin-kubernetes-cluster": "0.0.25",
|
||||
"@backstage/plugin-gateway-backend": "1.0.2",
|
||||
"@backstage/plugin-home": "0.8.9",
|
||||
"@backstage/plugin-home-react": "0.1.27",
|
||||
"@backstage/plugin-kubernetes": "0.12.8",
|
||||
"@backstage/plugin-kubernetes-backend": "0.19.7",
|
||||
"@backstage/plugin-kubernetes-cluster": "0.0.26",
|
||||
"@backstage/plugin-kubernetes-common": "0.9.5",
|
||||
"@backstage/plugin-kubernetes-node": "0.3.0",
|
||||
"@backstage/plugin-kubernetes-react": "0.5.7",
|
||||
"@backstage/plugin-notifications": "0.5.5",
|
||||
"@backstage/plugin-notifications-backend": "0.5.6",
|
||||
"@backstage/plugin-notifications-backend-module-email": "0.3.9",
|
||||
"@backstage/plugin-notifications-backend-module-slack": "0.1.1",
|
||||
"@backstage/plugin-notifications-common": "0.0.8",
|
||||
"@backstage/plugin-notifications-node": "0.2.15",
|
||||
"@backstage/plugin-org": "0.6.39",
|
||||
"@backstage/plugin-org-react": "0.1.38",
|
||||
"@backstage/plugin-permission-backend": "0.7.0",
|
||||
"@backstage/plugin-permission-backend-module-allow-all-policy": "0.2.8",
|
||||
"@backstage/plugin-kubernetes-node": "0.3.1",
|
||||
"@backstage/plugin-kubernetes-react": "0.5.8",
|
||||
"@backstage/plugin-mcp-actions-backend": "0.1.0",
|
||||
"@backstage/plugin-notifications": "0.5.6",
|
||||
"@backstage/plugin-notifications-backend": "0.5.7",
|
||||
"@backstage/plugin-notifications-backend-module-email": "0.3.10",
|
||||
"@backstage/plugin-notifications-backend-module-slack": "0.1.2",
|
||||
"@backstage/plugin-notifications-common": "0.0.9",
|
||||
"@backstage/plugin-notifications-node": "0.2.16",
|
||||
"@backstage/plugin-org": "0.6.40",
|
||||
"@backstage/plugin-org-react": "0.1.39",
|
||||
"@backstage/plugin-permission-backend": "0.7.1",
|
||||
"@backstage/plugin-permission-backend-module-allow-all-policy": "0.2.9",
|
||||
"@backstage/plugin-permission-common": "0.9.0",
|
||||
"@backstage/plugin-permission-node": "0.10.0",
|
||||
"@backstage/plugin-permission-react": "0.4.34",
|
||||
"@backstage/plugin-proxy-backend": "0.6.2",
|
||||
"@backstage/plugin-proxy-node": "0.1.4",
|
||||
"@backstage/plugin-scaffolder": "1.31.0",
|
||||
"@backstage/plugin-scaffolder-backend": "1.33.0",
|
||||
"@backstage/plugin-scaffolder-backend-module-azure": "0.2.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.3.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.3.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-gcp": "0.2.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-gitea": "0.2.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-github": "0.7.1",
|
||||
"@backstage/plugin-scaffolder-backend-module-gitlab": "0.9.1",
|
||||
"@backstage/plugin-scaffolder-backend-module-notifications": "0.1.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-rails": "0.5.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-sentry": "0.2.9",
|
||||
"@backstage/plugin-scaffolder-backend-module-yeoman": "0.4.10",
|
||||
"@backstage/plugin-permission-node": "0.10.1",
|
||||
"@backstage/plugin-permission-react": "0.4.35",
|
||||
"@backstage/plugin-proxy-backend": "0.6.3",
|
||||
"@backstage/plugin-proxy-node": "0.1.5",
|
||||
"@backstage/plugin-scaffolder": "1.32.0",
|
||||
"@backstage/plugin-scaffolder-backend": "2.0.0",
|
||||
"@backstage/plugin-scaffolder-backend-module-azure": "0.2.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.11",
|
||||
"@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.3.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.3.11",
|
||||
"@backstage/plugin-scaffolder-backend-module-gcp": "0.2.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-gitea": "0.2.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-github": "0.8.0",
|
||||
"@backstage/plugin-scaffolder-backend-module-gitlab": "0.9.2",
|
||||
"@backstage/plugin-scaffolder-backend-module-notifications": "0.1.11",
|
||||
"@backstage/plugin-scaffolder-backend-module-rails": "0.5.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-sentry": "0.2.10",
|
||||
"@backstage/plugin-scaffolder-backend-module-yeoman": "0.4.11",
|
||||
"@backstage/plugin-scaffolder-common": "1.5.11",
|
||||
"@backstage/plugin-scaffolder-node": "0.8.2",
|
||||
"@backstage/plugin-scaffolder-node-test-utils": "0.2.2",
|
||||
"@backstage/plugin-scaffolder-react": "1.16.0",
|
||||
"@backstage/plugin-search": "1.4.26",
|
||||
"@backstage/plugin-search-backend": "2.0.2",
|
||||
"@backstage/plugin-search-backend-module-catalog": "0.3.4",
|
||||
"@backstage/plugin-search-backend-module-elasticsearch": "1.7.2",
|
||||
"@backstage/plugin-search-backend-module-explore": "0.3.2",
|
||||
"@backstage/plugin-search-backend-module-pg": "0.5.44",
|
||||
"@backstage/plugin-search-backend-module-stack-overflow-collator": "0.3.9",
|
||||
"@backstage/plugin-search-backend-module-techdocs": "0.4.2",
|
||||
"@backstage/plugin-search-backend-node": "1.3.11",
|
||||
"@backstage/plugin-scaffolder-node": "0.9.0",
|
||||
"@backstage/plugin-scaffolder-node-test-utils": "0.3.0",
|
||||
"@backstage/plugin-scaffolder-react": "1.17.0",
|
||||
"@backstage/plugin-search": "1.4.27",
|
||||
"@backstage/plugin-search-backend": "2.0.3",
|
||||
"@backstage/plugin-search-backend-module-catalog": "0.3.5",
|
||||
"@backstage/plugin-search-backend-module-elasticsearch": "1.7.3",
|
||||
"@backstage/plugin-search-backend-module-explore": "0.3.3",
|
||||
"@backstage/plugin-search-backend-module-pg": "0.5.45",
|
||||
"@backstage/plugin-search-backend-module-stack-overflow-collator": "0.3.10",
|
||||
"@backstage/plugin-search-backend-module-techdocs": "0.4.3",
|
||||
"@backstage/plugin-search-backend-node": "1.3.12",
|
||||
"@backstage/plugin-search-common": "1.2.18",
|
||||
"@backstage/plugin-search-react": "1.9.0",
|
||||
"@backstage/plugin-signals": "0.0.19",
|
||||
"@backstage/plugin-signals-backend": "0.3.4",
|
||||
"@backstage/plugin-signals-node": "0.1.20",
|
||||
"@backstage/plugin-signals-react": "0.0.13",
|
||||
"@backstage/plugin-techdocs": "1.12.6",
|
||||
"@backstage/plugin-techdocs-addons-test-utils": "1.0.48",
|
||||
"@backstage/plugin-techdocs-backend": "2.0.2",
|
||||
"@backstage/plugin-techdocs-common": "0.1.0",
|
||||
"@backstage/plugin-techdocs-module-addons-contrib": "1.1.24",
|
||||
"@backstage/plugin-techdocs-node": "1.13.3",
|
||||
"@backstage/plugin-techdocs-react": "1.2.17",
|
||||
"@backstage/plugin-user-settings": "0.8.22",
|
||||
"@backstage/plugin-user-settings-backend": "0.3.2",
|
||||
"@backstage/plugin-search-react": "1.9.1",
|
||||
"@backstage/plugin-signals": "0.0.20",
|
||||
"@backstage/plugin-signals-backend": "0.3.5",
|
||||
"@backstage/plugin-signals-node": "0.1.21",
|
||||
"@backstage/plugin-signals-react": "0.0.14",
|
||||
"@backstage/plugin-techdocs": "1.13.0",
|
||||
"@backstage/plugin-techdocs-addons-test-utils": "1.0.49",
|
||||
"@backstage/plugin-techdocs-backend": "2.0.3",
|
||||
"@backstage/plugin-techdocs-common": "0.1.1",
|
||||
"@backstage/plugin-techdocs-module-addons-contrib": "1.1.25",
|
||||
"@backstage/plugin-techdocs-node": "1.13.4",
|
||||
"@backstage/plugin-techdocs-react": "1.3.0",
|
||||
"@backstage/plugin-user-settings": "0.8.23",
|
||||
"@backstage/plugin-user-settings-backend": "0.3.3",
|
||||
"@backstage/plugin-user-settings-common": "0.0.1"
|
||||
},
|
||||
"changesets": []
|
||||
"changesets": [
|
||||
"chubby-dots-kiss",
|
||||
"clear-bananas-end",
|
||||
"create-app-1751370514",
|
||||
"curly-zoos-thank",
|
||||
"cyan-islands-swim",
|
||||
"dark-cougars-go",
|
||||
"dry-hornets-stop",
|
||||
"eleven-pans-turn",
|
||||
"empty-mugs-agree",
|
||||
"empty-poets-give",
|
||||
"fancy-nails-call",
|
||||
"fuzzy-cooks-dress",
|
||||
"gentle-llamas-press",
|
||||
"mean-lemons-dream",
|
||||
"odd-clubs-teach",
|
||||
"petite-paths-remain",
|
||||
"public-nails-melt",
|
||||
"red-trams-join",
|
||||
"rich-eagles-rule",
|
||||
"shaggy-cobras-rhyme",
|
||||
"shaky-parents-enter",
|
||||
"sharp-stars-report",
|
||||
"silent-vans-tie",
|
||||
"six-dots-agree",
|
||||
"sixty-ties-matter",
|
||||
"social-insects-cheat",
|
||||
"stupid-donuts-sit",
|
||||
"three-shoes-behave",
|
||||
"tired-bats-attend",
|
||||
"wicked-socks-share",
|
||||
"wise-frogs-talk",
|
||||
"yummy-pugs-battle"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
'@backstage/canon': minor
|
||||
---
|
||||
|
||||
**BREAKING CHANGES**
|
||||
|
||||
We’re updating our Button component to provide better support for button links.
|
||||
|
||||
- We’re introducing a new `ButtonLink` component, which replaces the previous render prop pattern.
|
||||
- To maintain naming consistency across components, `IconButton` is being renamed to `ButtonIcon`.
|
||||
- Additionally, the render prop will be removed from all button-related components.
|
||||
|
||||
These changes aim to simplify usage and improve clarity in our component API.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-notifications-backend': patch
|
||||
---
|
||||
|
||||
Fix `addTopic` migration when `user_settings` present
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-mcp-actions-backend': patch
|
||||
---
|
||||
|
||||
Fixed the example in the README for generating a static token by adding a subject field
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/create-app': minor
|
||||
---
|
||||
|
||||
Add .cache directory to shipped gitignore.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Update return types for Heading & Text components for React 19.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
We are transforming how we structure our class names and data attributes definitions for all components. They are now all set in the same place.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/catalog-client': patch
|
||||
---
|
||||
|
||||
allow arrays in the InMemoryCatalogClient to filter entities
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Replaced deprecated uses of `@backstage/backend-common` with the equivalents in `@backstage/backend-defaults` and `@backstage/backend-plugin-api`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Added placeholder prop to TextField component.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
'@backstage/integration': patch
|
||||
---
|
||||
|
||||
UrlReader: Fix handling of access tokens for GitLab readURL requests
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/repo-tools': minor
|
||||
---
|
||||
|
||||
Add support for caching the per-package output from the `package-docs` command.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
|
||||
---
|
||||
|
||||
Fixing the typescript issue with using `z.unknown()`
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-github': patch
|
||||
---
|
||||
|
||||
Added support for file deletion to `publish:github:pull-request` action.
|
||||
|
||||
Example usage:
|
||||
|
||||
```diff
|
||||
- action: publish:github:pull-request
|
||||
id: clean-up-pr
|
||||
input:
|
||||
description: This is the description
|
||||
+ filesToDelete:
|
||||
+ - outdated/changelog.md
|
||||
+ - sample-file.txt
|
||||
owner: owner
|
||||
repo: repo
|
||||
title: Title Goes Here
|
||||
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-import': patch
|
||||
---
|
||||
|
||||
Fixed bug with error message since ResponseError is now thrown from CatalogClient
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
adding export for ButtonLink so it's importable
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/integration-react': patch
|
||||
---
|
||||
|
||||
Separated gitlab `write_repository` and `api` scope to pass checks in `RefreshingAuthSessionManager`
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/canon': minor
|
||||
---
|
||||
|
||||
Fixes spacing props on layout components and aligned on naming for the Grid component. You should now call the Grid root component using <Grid.Root /> instead of just <Grid />.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend': patch
|
||||
---
|
||||
|
||||
Error messages should not contain backend SQL query strings in the API response, this change will ensure that messages are logged and empty response is returned to the user
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
'@backstage/integration': patch
|
||||
---
|
||||
|
||||
Fixed bug where the GitLab user token and GitLab integration token were being merged together
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/canon': patch
|
||||
---
|
||||
|
||||
Remove leftover console.log from Container component.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/theme': patch
|
||||
---
|
||||
|
||||
Update uncomfortably bright color in recently visited and top visited home page cards
|
||||
+19
-1
@@ -18,8 +18,26 @@ var path = require('path');
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
plugins: ['@spotify', 'notice', 'react', 'testing-library'],
|
||||
plugins: ['@spotify', 'notice', 'react', 'testing-library', '@backstage'],
|
||||
rules: {
|
||||
'@backstage/no-mixed-plugin-imports': [
|
||||
'error',
|
||||
{
|
||||
// TODO: Fix these either by right role or by moving things to new packages
|
||||
excludedTargetPackages: [
|
||||
'@backstage/plugin-catalog',
|
||||
'@backstage/plugin-techdocs',
|
||||
'@backstage/plugin-app',
|
||||
'@backstage/plugin-catalog-backend',
|
||||
'@backstage/test-utils',
|
||||
'@backstage/plugin-auth-backend',
|
||||
'@backstage/plugin-permission-backend',
|
||||
'@backstage/plugin-kubernetes-backend',
|
||||
'@backstage/config-loader',
|
||||
'@backstage/plugin-app-backend'
|
||||
],
|
||||
}
|
||||
],
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
'notice/notice': [
|
||||
'error',
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
rangeStrategy: 'replace',
|
||||
matchSourceUrls: ['https://github.com/gregberge/svgr{/,}**'],
|
||||
},
|
||||
{
|
||||
groupName: 'Module-federation monorepo packages',
|
||||
rangeStrategy: 'replace',
|
||||
matchSourceUrls: ['https://github.com/module-federation/core{/,}**'],
|
||||
},
|
||||
// We update yarn packages manually as it's gzip'd and we don't want to pollute the repository too much.
|
||||
{
|
||||
matchSourceUrls: ['https://github.com/yarnpkg/berry'],
|
||||
|
||||
@@ -43,6 +43,7 @@ bugfixes
|
||||
builtins
|
||||
bundler
|
||||
bundlers
|
||||
bursty
|
||||
callout
|
||||
CDNs
|
||||
Chai
|
||||
@@ -433,6 +434,7 @@ statefulsets
|
||||
stdout
|
||||
storable
|
||||
storages
|
||||
Streamable
|
||||
stringified
|
||||
stringify
|
||||
subcommand
|
||||
|
||||
@@ -52,17 +52,17 @@ jobs:
|
||||
working-directory: ./example-app
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: './example-app'
|
||||
file: ./example-app/packages/backend/Dockerfile
|
||||
|
||||
@@ -321,12 +321,12 @@ jobs:
|
||||
name: storybook
|
||||
path: microsite/build/storybook
|
||||
|
||||
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
name: stable-reference-beta
|
||||
path: microsite/build/api/stable/
|
||||
|
||||
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
name: next-reference-beta
|
||||
path: microsite/build/api/next/
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
|
||||
|
||||
- name: Run Prettier on ADOPTERS.md
|
||||
uses: creyD/prettier_action@31355f8eef017f8aeba2e0bc09d8502b13dbbad1 # v4.3
|
||||
uses: creyD/prettier_action@8c18391fdc98ed0d884c6345f03975edac71b8f0 # v4.6
|
||||
with:
|
||||
# Modifies commit only if prettier autofixed the ADOPTERS.md
|
||||
prettier_options: --config docs/prettier.config.js --write ADOPTERS.md
|
||||
|
||||
@@ -325,13 +325,13 @@ jobs:
|
||||
working-directory: microsite
|
||||
|
||||
- name: download stable reference (beta)
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
name: stable-reference-beta
|
||||
path: api/stable/
|
||||
|
||||
- name: download next reference (beta)
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
name: next-reference-beta
|
||||
path: api/next/
|
||||
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
- run: yarn --cwd packages/canon build-storybook
|
||||
|
||||
- uses: chromaui/action@e8cc4c31775280b175a3c440076c00d19a9014d7 # v11
|
||||
- uses: chromaui/action@1cfa065cbdab28f6ca3afaeb3d761383076a35aa # v11
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# projectToken intentionally shared to allow collaborators to run Chromatic on forks
|
||||
|
||||
@@ -284,3 +284,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/
|
||||
| [Scalepoint](https://scalepoint.com) | [Yuriy Ostapenko](https://github.com/yuriyostapenko), [Dmytro Pasko](https://github.com/dimapasko), [Yuri Sedykh ](https://github.com/yuiri-sedykh), [Bartosz Wisniewski](https://github.com/Epgor) | Internal Developer Portal: Software Catalog with infrastructure resources and dependencies, Software Templates, TechDocs, Tech Radar, Kubernetes and Observability, as well as custom CI/CD components |
|
||||
| [VR](https://www.vr.com.br) | [Felipe Gomes](https://www.linkedin.com/in/felipe-gomes-da-silva), [Tiago Garcia](https://www.linkedin.com/in/tiago-garcia-6301a925) | Internal portal for development squads, service catalog, documentation hub, and application mapping for the entire company ecosystem, simplifying cloud infrastructure construction through templates. |
|
||||
| [Plata](https://platacard.mx/en) | [Shamil Ganiev](https://github.com/ganievs) | Internal Developer Portal for the whole engineering team |
|
||||
| [Syngenta Digital](https://www.syngentadigital.com) | [Bitan Mallick](https://www.linkedin.com/in/bitanmallick) | Internal developer portal, designed to empower developers and streamline workflows. We use software catalog, tech-radar, software templates, tech-docs and various custom plugins to ensure an efficient and collaborative development experience. |
|
||||
|
||||
@@ -26,6 +26,7 @@ These labels indicate what is needed to move an issue forward before it can be a
|
||||
|
||||
- `needs:bep` - The issue is an advanced addition that needs a [Backstage Enhancement Proposal](./beps/README.md).
|
||||
- `needs:direction` - The issue needs direction from the owners of the area.
|
||||
- `needs:discussion` - The way forward for this issue is unclear and it needs further discussion with the author and other participants.
|
||||
- `needs:more-info` - The issue needs more information from the author.
|
||||
- `needs:motivation` - It is not clear why this change is needed. The author should provide motivation for the change, for instance by giving examples of concrete use cases or scenarios.
|
||||
- `needs:repro` - The issue cannot be reproduced by the owners of the area. The author should provide more information to help them reproduce the issue, if possible with a minimal reproduction repository.
|
||||
@@ -81,11 +82,17 @@ These labels indicate that an issue is related to specific domains of expertise.
|
||||
- `domain:tooling` - Tooling and automation in Node.js and GitHub Actions.
|
||||
- `domain:web` - Frontend development using TypeScript and React.
|
||||
|
||||
## Workflow Labels
|
||||
|
||||
These labels indicate a workflow status for the owners.
|
||||
|
||||
- `workflow:do-not-merge` - The Pull Request should not be merged.
|
||||
- `workflow:before-release` - Should be handled before the next main-line release.
|
||||
- `workflow:after-release` - Should be handled after the next main-line release.
|
||||
- `workflow:after-vacations` - To be handled once the owners return from vacation.
|
||||
|
||||
## General Labels
|
||||
|
||||
- `after vacations` - To be handled once the owners return from vacation.
|
||||
- `do not merge` - The pull request should not be merged.
|
||||
- `fix before release` - Should be handled before the next release.
|
||||
- `good first issue` - Good for new contributors.
|
||||
- `stale` - The issue or pull request has not seen any activity for a while and will be closed if no further activity is seen.
|
||||
- `no stale` - The issue or pull request should not be closed due to inactivity.
|
||||
|
||||
@@ -56,6 +56,18 @@ Scope: The Backstage design system, component library, as well as surrounding to
|
||||
| Charles de Dreuille | Spotify | | [cdedreuille](https://github.com/cdedreuille) | `cdedreuille` |
|
||||
| Patrik Oldsberg | Spotify | Cubic Belugas | [Rugvip](https://github.com/Rugvip) | `Rugvip` |
|
||||
|
||||
### Documentation
|
||||
|
||||
Team: @backstage/documentation-maintainers
|
||||
|
||||
Scope: The Backstage Documentation and Microsite, excluding the plugins listing
|
||||
|
||||
| Name | Organization | GitHub | Discord |
|
||||
| --------------- | ------------- | ----------------------------------------------------- | ------------- |
|
||||
| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` |
|
||||
| Aramis Sennyey | DoorDash | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` |
|
||||
| Peter Macdonald | VodafoneZiggo | [Parsifal-M](https://github.com/Parsifal-M) | `parsifal` |
|
||||
|
||||
### Framework
|
||||
|
||||
Team: @backstage/framework-maintainers
|
||||
@@ -77,11 +89,11 @@ Team: @backstage/helm-chart-maintainers
|
||||
|
||||
Scope: The Backstage [Helm Chart(s)](https://github.com/backstage/charts).
|
||||
|
||||
| Name | Organization | Team | GitHub | Discord |
|
||||
| -------------------- | ------------ | ---- | ---------------------------------------- | -------------- |
|
||||
| Andrew Block | Red Hat | | [sabre1041](http://github.com/sabre1041) | sabre1041#2622 |
|
||||
| Tom Coufal | Red Hat | | [tumido](http://github.com/tumido) | Tumi#4346 |
|
||||
| Vincenzo Scamporlino | Spotify | | [vinzscam](http://github.com/vinzscam) | vinzscam#6944 |
|
||||
| Name | Organization | Team | GitHub | Discord |
|
||||
| -------------------- | ------------ | ---- | ---------------------------------------- | ---------------- |
|
||||
| Andrew Block | Red Hat | | [sabre1041](http://github.com/sabre1041) | `sabre1041#2622` |
|
||||
| Tom Coufal | Red Hat | | [tumido](http://github.com/tumido) | `Tumi#4346` |
|
||||
| Vincenzo Scamporlino | Spotify | | [vinzscam](http://github.com/vinzscam) | `vinzscam#6944` |
|
||||
|
||||
### Home
|
||||
|
||||
@@ -89,12 +101,14 @@ Team: @backstage/home-maintainers
|
||||
|
||||
Scope: The Backstage home page and information architecture
|
||||
|
||||
| Name | Organization | Team | GitHub | Discord |
|
||||
| ------------------------ | ------------ | -------------- | ---------------------------------------- | ----------------- |
|
||||
| Avantika Iyer | Spotify | Infinite Buck$ | [tikabom](http://github.com/tikabom) | - |
|
||||
| Emma Indal | Spotify | Infinite Buck$ | [emmaindal](http://github.com/emmaindal) | emmaindal#7503 |
|
||||
| Djamaile Rahamat | Spotify | Infinite Buck$ | [djamaile](http://github.com/djamaile) | dyoqi |
|
||||
| Raghunandan Balachandran | Spotify | Infinite Buck$ | [soapraj](http://github.com/soapraj) | raghunandanb#1114 |
|
||||
| Name | Organization | Team | GitHub | Discord |
|
||||
| ------------------ | ------------ | --------------- | ----------------------------------------- | ------- |
|
||||
| Ainhoa Larumbe | Spotify | Imaginary Goats | [ainhoaL](http://github.com/ainhoaL) | - |
|
||||
| Avantika Iyer | Spotify | Imaginary Goats | [tikabom](http://github.com/tikabom) | - |
|
||||
| Daniel Jelčić | Spotify | Imaginary Goats | [djelcic](http://github.com/danieljelcic) | - |
|
||||
| Eric Peterson | Spotify | Imaginary Goats | [iamEAP](http://github.com/iamEAP) | - |
|
||||
| Musaab Elfaqih | Spotify | Imaginary Goats | [TheSabby](http://github.com/TheSabby) | - |
|
||||
| Landry Zinda-Snead | Spotify | Imaginary Goats | [landryzs](http://github.com/landryzs) | - |
|
||||
|
||||
### Kubernetes
|
||||
|
||||
@@ -206,18 +220,6 @@ Scope: Tooling and Community Repo Maintainers for the Backstage [Community Plugi
|
||||
| Vincenzo Scamporlino | Spotify | [vinzscam](https://github.com/vinzscam) | `vinzscam` |
|
||||
| Peter Macdonald | VodafoneZiggo | [Parsifal-M](https://github.com/Parsifal-M) | `parsifal` |
|
||||
|
||||
### Documentation
|
||||
|
||||
Team: @backstage/documentation-maintainers
|
||||
|
||||
Scope: The Backstage Documentation and Microsite, excluding the plugins listing
|
||||
|
||||
| Name | Organization | GitHub | Discord |
|
||||
| --------------- | ------------- | ----------------------------------------------------- | ------------- |
|
||||
| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` |
|
||||
| Aramis Sennyey | DoorDash | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` |
|
||||
| Peter Macdonald | VodafoneZiggo | [Parsifal-M](https://github.com/Parsifal-M) | `parsifal` |
|
||||
|
||||
### Events
|
||||
|
||||
Team: @backstage/events-maintainers
|
||||
|
||||
+11
-212
@@ -36,6 +36,12 @@ backend:
|
||||
# keys:
|
||||
# - secret: ${BACKEND_SECRET}
|
||||
|
||||
# Used for testing rate limiting locally
|
||||
# rateLimit:
|
||||
# windowMs: 1m
|
||||
# incomingRequestLimit: 1
|
||||
# ipAllowList: []
|
||||
|
||||
auth:
|
||||
# TODO: once plugins have been migrated we can remove this, but right now it
|
||||
# is require for the backend-next to work in this repo
|
||||
@@ -64,83 +70,11 @@ backend:
|
||||
# See README.md in the proxy-backend plugin for information on the configuration format
|
||||
proxy:
|
||||
endpoints:
|
||||
'/circleci/api':
|
||||
target: https://circleci.com/api/v1.1
|
||||
headers:
|
||||
Circle-Token: ${CIRCLECI_AUTH_TOKEN}
|
||||
|
||||
'/jenkins/api':
|
||||
target: http://localhost:8080
|
||||
headers:
|
||||
Authorization: ${JENKINS_BASIC_AUTH_HEADER}
|
||||
|
||||
'/travisci/api':
|
||||
target: https://api.travis-ci.com
|
||||
changeOrigin: true
|
||||
headers:
|
||||
Authorization: ${TRAVISCI_AUTH_TOKEN}
|
||||
travis-api-version: '3'
|
||||
|
||||
'/newrelic/apm/api':
|
||||
target: https://api.newrelic.com/v2
|
||||
headers:
|
||||
X-Api-Key: ${NEW_RELIC_REST_API_KEY}
|
||||
allowedHeaders:
|
||||
- link
|
||||
|
||||
'/newrelic/api':
|
||||
target: https://api.newrelic.com
|
||||
headers:
|
||||
X-Api-Key: ${NEW_RELIC_USER_KEY}
|
||||
|
||||
'/pagerduty':
|
||||
target: https://api.pagerduty.com
|
||||
headers:
|
||||
Authorization: Token token=${PAGERDUTY_TOKEN}
|
||||
|
||||
'/buildkite/api':
|
||||
target: https://api.buildkite.com/v2/
|
||||
headers:
|
||||
Authorization: ${BUILDKITE_TOKEN}
|
||||
|
||||
'/sentry/api':
|
||||
target: https://sentry.io/api/
|
||||
allowedMethods: ['GET']
|
||||
headers:
|
||||
Authorization: ${SENTRY_TOKEN}
|
||||
|
||||
'/ilert':
|
||||
target: https://api.ilert.com
|
||||
allowedMethods: ['GET', 'POST', 'PUT']
|
||||
allowedHeaders: ['Authorization']
|
||||
headers:
|
||||
Authorization: ${ILERT_AUTH_HEADER}
|
||||
|
||||
'/airflow':
|
||||
target: https://your.airflow.instance.com/api/v1
|
||||
headers:
|
||||
Authorization: ${AIRFLOW_BASIC_AUTH_HEADER}
|
||||
|
||||
'/gocd':
|
||||
target: https://your.gocd.instance.com/go/api
|
||||
allowedMethods: ['GET']
|
||||
allowedHeaders: ['Authorization']
|
||||
headers:
|
||||
Authorization: Basic ${GOCD_AUTH_CREDENTIALS}
|
||||
|
||||
'/dynatrace':
|
||||
target: https://your.dynatrace.instance.com/api/v2
|
||||
headers:
|
||||
Authorization: 'Api-Token ${DYNATRACE_ACCESS_TOKEN}'
|
||||
|
||||
'/stackstorm':
|
||||
target: https://your.stackstorm.instance.com/api
|
||||
headers:
|
||||
St2-Api-Key: ${ST2_API_KEY}
|
||||
|
||||
'/puppetdb':
|
||||
target: https://your.puppetdb.instance.com
|
||||
|
||||
organization:
|
||||
name: My Company
|
||||
|
||||
@@ -157,46 +91,6 @@ techdocs:
|
||||
publisher:
|
||||
type: 'local' # Alternatives - 'googleGcs' or 'awsS3' or 'azureBlobStorage' or 'openStackSwift'. Read documentation for using alternatives.
|
||||
|
||||
dynatrace:
|
||||
baseUrl: https://your.dynatrace.instance.com
|
||||
|
||||
nomad:
|
||||
addr: 0.0.0.0
|
||||
|
||||
# Score-cards sample configuration.
|
||||
scorecards:
|
||||
jsonDataUrl: https://raw.githubusercontent.com/Oriflame/backstage-plugins/main/plugins/score-card/sample-data/
|
||||
wikiLinkTemplate: https://link-to-wiki/{id}
|
||||
|
||||
sentry:
|
||||
organization: my-company
|
||||
|
||||
rollbar:
|
||||
organization: my-company
|
||||
# NOTE: The rollbar-backend & accountToken key may be deprecated in the future (replaced by a proxy config)
|
||||
accountToken: my-rollbar-account-token
|
||||
|
||||
lighthouse:
|
||||
baseUrl: http://localhost:3003
|
||||
|
||||
kubernetes:
|
||||
serviceLocatorMethod:
|
||||
type: 'multiTenant'
|
||||
clusterLocatorMethods:
|
||||
- type: 'config'
|
||||
clusters: []
|
||||
|
||||
kafka:
|
||||
clientId: backstage
|
||||
clusters:
|
||||
- name: cluster
|
||||
dashboardUrl: https://akhq.io/
|
||||
brokers:
|
||||
- localhost:9092
|
||||
|
||||
allure:
|
||||
baseUrl: http://localhost:5050/allure-docker-service
|
||||
|
||||
integrations:
|
||||
github:
|
||||
- host: github.com
|
||||
@@ -244,7 +138,6 @@ integrations:
|
||||
secretAccessKey: ${AWS_SECRET_ACCESS_KEY}
|
||||
|
||||
catalog:
|
||||
useUrlReadersSearch: true
|
||||
import:
|
||||
entityFilename: catalog-info.yaml
|
||||
pullRequestBranchName: backstage-integration
|
||||
@@ -269,26 +162,6 @@ catalog:
|
||||
plugins:
|
||||
- catalog
|
||||
- search
|
||||
|
||||
processors:
|
||||
ldapOrg:
|
||||
### Example for how to add your enterprise LDAP server
|
||||
# providers:
|
||||
# - target: ldaps://ds.example.net
|
||||
# bind:
|
||||
# dn: uid=ldap-reader-user,ou=people,ou=example,dc=example,dc=net
|
||||
# secret: ${LDAP_SECRET}
|
||||
# users:
|
||||
# dn: ou=people,ou=example,dc=example,dc=net
|
||||
# options:
|
||||
# filter: (uid=*)
|
||||
# map:
|
||||
# description: l
|
||||
# groups:
|
||||
# dn: ou=access,ou=groups,ou=example,dc=example,dc=net
|
||||
# options:
|
||||
# filter: (&(objectClass=some-group-class)(!(groupType=email)))
|
||||
|
||||
locations:
|
||||
# Add a location here to ingest it, for example from a URL:
|
||||
#
|
||||
@@ -325,13 +198,14 @@ catalog:
|
||||
target: ../../plugins/scaffolder-backend/sample-templates/all-templates.yaml
|
||||
rules:
|
||||
- allow: [Template]
|
||||
|
||||
scaffolder:
|
||||
# Use to customize default commit author info used when new components are created
|
||||
# defaultAuthor:
|
||||
# name: Scaffolder
|
||||
# email: scaffolder@backstage.io
|
||||
defaultAuthor:
|
||||
name: Scaffolder
|
||||
email: scaffolder@backstage.io
|
||||
# Use to customize the default commit message when new components are created
|
||||
# defaultCommitMessage: 'Initial commit'
|
||||
defaultCommitMessage: 'Initial commit'
|
||||
|
||||
auth:
|
||||
### Add auth.keyStore.provider to more granularly control how to store JWK data when running
|
||||
@@ -422,80 +296,5 @@ auth:
|
||||
myproxy: {}
|
||||
guest: {}
|
||||
|
||||
costInsights:
|
||||
engineerCost: 200000
|
||||
engineerThreshold: 0.5
|
||||
products:
|
||||
computeEngine:
|
||||
name: Compute Engine
|
||||
icon: compute
|
||||
cloudDataflow:
|
||||
name: Cloud Dataflow
|
||||
icon: data
|
||||
cloudStorage:
|
||||
name: Cloud Storage
|
||||
icon: storage
|
||||
bigQuery:
|
||||
name: BigQuery
|
||||
icon: search
|
||||
events:
|
||||
name: Events
|
||||
icon: data
|
||||
metrics:
|
||||
DAU:
|
||||
name: Daily Active Users
|
||||
default: true
|
||||
MSC:
|
||||
name: Monthly Subscribers
|
||||
currencies:
|
||||
engineers:
|
||||
label: 'Engineers 🛠'
|
||||
unit: 'engineer'
|
||||
usd:
|
||||
label: 'US Dollars 💵'
|
||||
kind: 'USD'
|
||||
unit: 'dollar'
|
||||
prefix: '$'
|
||||
rate: 1
|
||||
carbonOffsetTons:
|
||||
label: 'Carbon Offset Tons ♻️⚖️s'
|
||||
kind: 'CARBON_OFFSET_TONS'
|
||||
unit: 'carbon offset ton'
|
||||
rate: 3.5
|
||||
beers:
|
||||
label: 'Beers 🍺'
|
||||
kind: 'BEERS'
|
||||
unit: 'beer'
|
||||
rate: 4.5
|
||||
pintsIceCream:
|
||||
label: 'Pints of Ice Cream 🍦'
|
||||
kind: 'PINTS_OF_ICE_CREAM'
|
||||
unit: 'ice cream pint'
|
||||
rate: 5.5
|
||||
|
||||
pagerDuty:
|
||||
eventsBaseUrl: 'https://events.pagerduty.com/v2'
|
||||
|
||||
jenkins:
|
||||
instances:
|
||||
- name: default
|
||||
baseUrl: https://jenkins.example.com
|
||||
username: backstage-bot
|
||||
apiKey: 123456789abcdef0123456789abcedf012
|
||||
|
||||
azureDevOps:
|
||||
host: dev.azure.com
|
||||
token: my-token
|
||||
organization: my-company
|
||||
|
||||
apacheAirflow:
|
||||
baseUrl: https://your.airflow.instance.com
|
||||
|
||||
gocd:
|
||||
baseUrl: https://your.gocd.instance.com
|
||||
|
||||
stackstorm:
|
||||
webUrl: https://your.stackstorm.webui.instance.com
|
||||
|
||||
permission:
|
||||
enabled: true
|
||||
|
||||
@@ -8,6 +8,11 @@ const nextConfig = {
|
||||
images: {
|
||||
unoptimized: true,
|
||||
},
|
||||
typescript: {
|
||||
// Ignore TypeScript errors during build - safe for React 18/19 compatibility issues
|
||||
// These are type-level conflicts that don't affect runtime behavior
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
};
|
||||
|
||||
const withMDX = createMDX({});
|
||||
|
||||
+23
-10
@@ -3,24 +3,35 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "npm run build:css && next build",
|
||||
"build:css": "node scripts/build-css.js",
|
||||
"prebuild": "yarn sync:css",
|
||||
"build": "next build",
|
||||
"lint": "next lint",
|
||||
"start": "npm run build:css && next dev"
|
||||
"prestart": "yarn sync:css",
|
||||
"start": "concurrently \"yarn sync:css:watch\" \"next dev\"",
|
||||
"sync:css": "node scripts/sync-css.js",
|
||||
"sync:css:watch": "node scripts/sync-css.js --watch"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "19.1.8",
|
||||
"@types/react-dom": "19.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/lang-sass": "^6.0.2",
|
||||
"@codemirror/view": "^6.34.4",
|
||||
"@lezer/highlight": "^1.2.1",
|
||||
"@mdx-js/loader": "^3.1.0",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"@next/mdx": "^15.1.4",
|
||||
"@next/mdx": "15.3.4",
|
||||
"@storybook/react": "^8.6.8",
|
||||
"@uiw/codemirror-themes": "^4.23.7",
|
||||
"@uiw/react-codemirror": "^4.23.7",
|
||||
"html-react-parser": "^5.2.5",
|
||||
"motion": "^12.4.1",
|
||||
"next": "14.2.26",
|
||||
"react": "^18.0.2",
|
||||
"react-dom": "^18.0.2",
|
||||
"next": "15.3.4",
|
||||
"next-mdx-remote-client": "^2.1.2",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-frame-component": "^5.2.7",
|
||||
"shiki": "^1.26.1",
|
||||
"storybook": "^8.6.8"
|
||||
@@ -28,10 +39,12 @@
|
||||
"devDependencies": {
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"@types/react": "19.1.8",
|
||||
"@types/react-dom": "19.1.6",
|
||||
"chokidar": "^3.6.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.2.23",
|
||||
"eslint-config-next": "15.3.4",
|
||||
"lightningcss": "^1.28.2",
|
||||
"typescript": "^5"
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 14 KiB |
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
@font-face{font-family:CircularSp;font-weight:700;font-display:swap;unicode-range:U+0,U+D,U+20-7E,U+A0-17E,U+18F,U+192,U+1A0-1A1,U+1AF-1B0,U+1B5-1B6,U+1C4-1C6,U+1F1-1F3,U+1FA-1FF,U+218-21B,U+237,U+259,U+2BB-2BC,U+2C6-2C7,U+2C9,U+2D8-2DD,U+300-301,U+303,U+309,U+323,U+394,U+3A9,U+3BC,U+3C0,U+1E80-1E85,U+1E8A-1E8B,U+1EA0-1EF9,U+1FD6,U+2007-2008,U+200B,U+2010-2011,U+2013-2014,U+2018-201A,U+201C-201E,U+2020-2022,U+2026,U+2030,U+2032-2033,U+2039-203A,U+2042,U+2044,U+2051,U+2070,U+2074-2079,U+2080-2089,U+20AB-20AC,U+2113,U+2117,U+2122,U+2126,U+2160-2169,U+216C-216F,U+2190-2193,U+2196-2199,U+21A9,U+21B0-21B5,U+21C6,U+2202,U+2206,U+220F,U+2211-2212,U+2215,U+2219-221A,U+221E,U+222B,U+2248,U+2260,U+2264-2265,U+22C5,U+24C5,U+25A0-25A1,U+25AF,U+25B2-25B3,U+25CA-25CB,U+25CF,U+262E,U+2713,U+2715,U+2780-2788,U+E000,U+E002,U+F6C3,U+FB00-FB04,U+FEFF,U+FF0C,U+FF0E,U+FF1A-FF1B,U+FFFF;src:url(https://encore.scdn.co/fonts/CircularSp-Bold-602e7aefc706aa36c6ec1324b9bbc461.woff2)format("woff2"),url(https://encore.scdn.co/fonts/CircularSp-Bold-856afe2da4ba4e61239b129e2c16d633.woff)format("woff")}[data-theme=dark][data-theme-name=spotify]{--canon-font-text:CircularSp,CircularSp-Arab,CircularSp-Hebr,CircularSp-Cyrl,CircularSp-Grek,CircularSp-Deva;--canon-font-title:CircularSpTitle,CircularSp-Arab,CircularSp-Hebr,CircularSp-Cyrl,CircularSp-Grek,CircularSp-Deva;--canon-font-regular:CircularSp,CircularSp-Arab,CircularSp-Hebr,CircularSp-Cyrl,CircularSp-Grek,CircularSp-Deva;--canon-gray-1:#191919;--canon-gray-2:#242424;--canon-gray-3:#373737;--canon-gray-4:#464646;--canon-gray-5:#575757;--canon-gray-6:#7b7b7b;--canon-gray-7:#9e9e9e;--canon-gray-8:#b4b4b4;--canon-bg:#000;--canon-bg-surface-1:#191919;--canon-bg-surface-2:#242424;--canon-bg-solid:#1ed760;--canon-bg-solid-hover:#3be477;--canon-bg-solid-pressed:#1abc54;--canon-bg-solid-disabled:#0f6c30;--canon-bg-tint:#242424;--canon-bg-tint-hover:#202020;--canon-bg-tint-pressed:#292929;--canon-bg-tint-disabled:#fffc;--canon-bg-danger:#3b1219;--canon-bg-warning:#302008;--canon-bg-success:#132d21;--canon-bg-underline:#d16ecb;--canon-fg-primary:#fff;--canon-fg-secondary:#9e9e9e;--canon-fg-link:#fff;--canon-fg-link-hover:#fff;--canon-fg-disabled:#575757;--canon-fg-solid:#000;--canon-fg-solid-disabled:#083618;--canon-fg-tint:#fff;--canon-fg-tint-disabled:#575757;--canon-fg-danger:#e22b2b;--canon-fg-warning:#e36d05;--canon-fg-success:#1db954;--canon-border:var(--canon-gray-3);--canon-border-hover:#fff6;--canon-border-pressed:#ffffff80;--canon-border-disabled:#fff3;--canon-border-danger:#f87a7a;--canon-border-warning:#e36d05;--canon-border-success:#53db83;--canon-ring:#fff3}#root{padding-top:var(--header-height)}.canon-Button,.canon-IconButton{border-radius:var(--canon-radius-3);transition:background-color .2s ease-in-out,color .2s ease-in-out,box-shadow .2s ease-in-out}.canon-Button--variant-primary,.canon-IconButton--variant-primary{&:hover{box-shadow:inset 0 0 0 1px var(--canon-bg-solid);color:var(--canon-fg-primary);background-color:#0000}&:active{background-color:#1ed7601a}&:disabled{background-color:var(--canon-bg-solid-disabled);color:var(--canon-fg-solid-disabled);box-shadow:none}}.canon-Button[data-size=medium],.canon-Button[data-size=small]{padding-inline:var(--canon-space-3)}.canon-MenuTrigger{all:unset;display:inline-flex}.canon-MenuPopup{box-sizing:border-box;max-width:21.25rem}.canon-MenuSubmenuTrigger,.canon-MenuItem{height:auto;min-height:2rem}.canon-Text{font-family:var(--canon-font-text)}.canon-Heading{font-family:var(--canon-font-title)}.canon-TableRow{border-radius:var(--canon-radius-4);border:none}.canon-TableRow:hover td:first-child{border-top-left-radius:var(--canon-radius-2);border-bottom-left-radius:var(--canon-radius-2)}.canon-TableRow:hover td:last-child{border-top-right-radius:var(--canon-radius-2);border-bottom-right-radius:var(--canon-radius-2)}.canon-TableBody:before,.canon-TableBody:after{line-height:var(--canon-space-1);content:"";display:block}.canon-TableHeader .canon-TableRow{border-bottom:1px solid var(--canon-border)}.canon-TableHead{font-size:var(--canon-font-size-2);color:var(--canon-fg-secondary);font-weight:var(--canon-font-weight-regular)}.canon-ScrollAreaRoot{width:100%;height:unset}.canon-TabsIndicator{background-color:var(--canon-bg-underline)}.canon-TabsTab[data-selected]{background:radial-gradient(at bottom,#d16ecb40 0%,#0000 95%)}
|
||||
@@ -1,39 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { bundle } = require('lightningcss');
|
||||
|
||||
const source = '../../packages/canon/src/css';
|
||||
const destination = '../public';
|
||||
|
||||
const source1 = path.join(__dirname, `${source}/core.css`);
|
||||
const destination1 = path.join(__dirname, `${destination}/core.css`);
|
||||
const source2 = path.join(__dirname, `${source}/components.css`);
|
||||
const destination2 = path.join(__dirname, `${destination}/components.css`);
|
||||
|
||||
// Function to bundle and copy the CSS file
|
||||
const bundleAndCopyFile = async (source, destination) => {
|
||||
try {
|
||||
const result = await bundle({
|
||||
filename: source,
|
||||
minify: true,
|
||||
});
|
||||
|
||||
fs.writeFileSync(destination, result.code);
|
||||
console.log('File bundled and copied successfully!');
|
||||
} catch (err) {
|
||||
console.error('Error bundling file:', err);
|
||||
}
|
||||
};
|
||||
|
||||
// Initial bundle and copy
|
||||
Promise.all([
|
||||
bundleAndCopyFile(source1, destination1),
|
||||
bundleAndCopyFile(source2, destination2),
|
||||
])
|
||||
.then(() => {
|
||||
// Add an empty line after all operations are complete - It looks better in the terminal :)
|
||||
console.log('');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Error in processing files:', err);
|
||||
});
|
||||
@@ -0,0 +1,149 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { bundle } = require('lightningcss');
|
||||
const chokidar = require('chokidar');
|
||||
|
||||
// Configuration
|
||||
const config = {
|
||||
canonPath: '../../packages/canon',
|
||||
publicPath: '../public',
|
||||
files: [
|
||||
{
|
||||
source: 'css/styles.css',
|
||||
destination: 'theme-backstage.css',
|
||||
name: 'Main Styles',
|
||||
},
|
||||
{
|
||||
source: '.storybook/themes/spotify.css',
|
||||
destination: 'theme-spotify.css',
|
||||
name: 'Spotify Theme',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
class CSSSync {
|
||||
constructor() {
|
||||
this.canonPath = path.resolve(__dirname, config.canonPath);
|
||||
this.publicPath = path.resolve(__dirname, config.publicPath);
|
||||
this.isWatching = process.argv.includes('--watch');
|
||||
}
|
||||
|
||||
async syncFile(fileConfig) {
|
||||
const sourcePath = path.join(this.canonPath, fileConfig.source);
|
||||
const destPath = path.join(this.publicPath, fileConfig.destination);
|
||||
|
||||
try {
|
||||
// Check if source file exists
|
||||
if (!fs.existsSync(sourcePath)) {
|
||||
console.warn(`⚠️ Source file not found: ${sourcePath}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure destination directory exists
|
||||
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
||||
|
||||
// Bundle and optimize CSS
|
||||
const result = await bundle({
|
||||
filename: sourcePath,
|
||||
minify: true,
|
||||
});
|
||||
|
||||
// Write to destination
|
||||
fs.writeFileSync(destPath, result.code);
|
||||
|
||||
console.log(
|
||||
`✅ ${fileConfig.name}: ${fileConfig.source} → ${fileConfig.destination}`,
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`❌ Error syncing ${fileConfig.name}:`, error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async syncAll() {
|
||||
console.log('🔄 Syncing CSS files...\n');
|
||||
|
||||
let successCount = 0;
|
||||
for (const fileConfig of config.files) {
|
||||
if (await this.syncFile(fileConfig)) {
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`\n✨ Synced ${successCount}/${config.files.length} CSS files successfully!`,
|
||||
);
|
||||
|
||||
if (successCount > 0) {
|
||||
console.log('\n📁 Available CSS files in public/:');
|
||||
config.files.forEach(file => {
|
||||
const destPath = path.join(this.publicPath, file.destination);
|
||||
if (fs.existsSync(destPath)) {
|
||||
const stats = fs.statSync(destPath);
|
||||
const size = (stats.size / 1024).toFixed(2);
|
||||
console.log(` • ${file.destination} (${size} KB)`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
startWatching() {
|
||||
console.log('👀 Watching for CSS changes...\n');
|
||||
|
||||
// Watch all source files
|
||||
const watchPaths = config.files.map(file =>
|
||||
path.join(this.canonPath, file.source),
|
||||
);
|
||||
|
||||
const watcher = chokidar.watch(watchPaths, {
|
||||
ignored: /node_modules/,
|
||||
persistent: true,
|
||||
});
|
||||
|
||||
watcher.on('change', async filePath => {
|
||||
console.log(
|
||||
`\n🔄 Change detected: ${path.relative(this.canonPath, filePath)}`,
|
||||
);
|
||||
|
||||
// Find which file changed and sync it
|
||||
const fileConfig = config.files.find(file =>
|
||||
filePath.endsWith(file.source.replace(/\//g, path.sep)),
|
||||
);
|
||||
|
||||
if (fileConfig) {
|
||||
await this.syncFile(fileConfig);
|
||||
}
|
||||
});
|
||||
|
||||
watcher.on('error', error => console.error('❌ Watch error:', error));
|
||||
|
||||
// Handle process termination
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n👋 Stopping CSS sync...');
|
||||
watcher.close();
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
async run() {
|
||||
console.log('🎨 Canon CSS Sync Tool\n');
|
||||
console.log(`📂 Canon path: ${this.canonPath}`);
|
||||
console.log(`📂 Public path: ${this.publicPath}\n`);
|
||||
|
||||
// Initial sync
|
||||
await this.syncAll();
|
||||
|
||||
// Watch for changes if requested
|
||||
if (this.isWatching) {
|
||||
this.startWatching();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run the sync tool
|
||||
const cssSync = new CSSSync();
|
||||
cssSync.run().catch(error => {
|
||||
console.error('❌ CSS Sync failed:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Changelog } from '@/components/Changelog';
|
||||
|
||||
# Changelog
|
||||
|
||||
<Changelog />
|
||||
|
||||
## Version 0.1.0
|
||||
|
||||
We're excited to share the initial release of Canon 💚 In this first alpha version,
|
||||
you'll find the foundation of our design system: a set of versatile layout components
|
||||
and a handful of essential atomic elements to help you get started. While Canon is
|
||||
still in its early stages, it's ready for exploration and we'd love for you to give
|
||||
it a try and share your feedback.
|
||||
@@ -0,0 +1,25 @@
|
||||
import { components, layoutComponents } from '@/utils/data';
|
||||
|
||||
export default async function Page({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>;
|
||||
}) {
|
||||
const { slug } = await params;
|
||||
|
||||
const { default: Component } = await import(
|
||||
`@/content/components/${slug}.mdx`
|
||||
);
|
||||
|
||||
return <Component />;
|
||||
}
|
||||
|
||||
export function generateStaticParams() {
|
||||
const list = [...components, ...layoutComponents];
|
||||
|
||||
return list.map(component => ({
|
||||
slug: component.slug,
|
||||
}));
|
||||
}
|
||||
|
||||
export const dynamicParams = false;
|
||||
@@ -1,75 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { AvatarSnippet } from '@/snippets/stories-snippets';
|
||||
import { avatarPropDefs } from './props';
|
||||
|
||||
# Avatar
|
||||
|
||||
An avatar component with a fallback for initials.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<AvatarSnippet story="Default" />}
|
||||
code={`<Avatar src="https://avatars.githubusercontent.com/u/1540635?v=4" name="Charles de Dreuille" />`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Avatar } from '@backstage/canon';
|
||||
|
||||
<Avatar src="https://avatars.githubusercontent.com/u/1540635?v=4" name="Charles de Dreuille" />`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
- `canon-AvatarRoot`
|
||||
- `canon-AvatarRoot[data-size='small']`
|
||||
- `canon-AvatarRoot[data-size='medium']`
|
||||
- `canon-AvatarRoot[data-size='large']`
|
||||
- `canon-AvatarImage`
|
||||
- `canon-AvatarFallback`
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={avatarPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Sizes
|
||||
|
||||
Avatar sizes can be set using the `size` prop.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<AvatarSnippet story="Sizes" />}
|
||||
code={`<Flex gap="4" direction="column">
|
||||
<Avatar src="https://avatars.githubusercontent.com/u/1540635?v=4" name="Charles de Dreuille" size="small" />
|
||||
<Avatar src="https://avatars.githubusercontent.com/u/1540635?v=4" name="Charles de Dreuille" size="medium" />
|
||||
<Avatar src="https://avatars.githubusercontent.com/u/1540635?v=4" name="Charles de Dreuille" size="large" />
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Fallback
|
||||
|
||||
If the image is not available, the avatar will show the initials of the name.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<AvatarSnippet story="Fallback" />}
|
||||
code={`<Avatar src="https://avatars.githubusercontent.com/u/15406AAAAAAAAA" name="Charles de Dreuille" />`}
|
||||
/>
|
||||
@@ -1,19 +0,0 @@
|
||||
import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs';
|
||||
import type { PropDef } from '@/utils/propDefs';
|
||||
|
||||
export const avatarPropDefs: Record<string, PropDef> = {
|
||||
src: {
|
||||
type: 'string',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
size: {
|
||||
type: 'enum',
|
||||
values: ['small', 'medium', 'large'],
|
||||
default: 'medium',
|
||||
responsive: true,
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
import {
|
||||
classNamePropDefs,
|
||||
displayPropDefs,
|
||||
heightPropDefs,
|
||||
positionPropDefs,
|
||||
stylePropDefs,
|
||||
widthPropDefs,
|
||||
} from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const boxPropDefs: Record<string, PropDef> = {
|
||||
as: {
|
||||
type: 'enum',
|
||||
values: ['div', 'span'],
|
||||
default: 'div',
|
||||
responsive: true,
|
||||
},
|
||||
...widthPropDefs,
|
||||
...heightPropDefs,
|
||||
...positionPropDefs,
|
||||
...displayPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,136 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { ButtonSnippet } from '@/snippets/stories-snippets';
|
||||
import { buttonVariants } from '@/snippets/code-snippets';
|
||||
import { buttonPropDefs } from './props';
|
||||
|
||||
# Button
|
||||
|
||||
A button component that can be used to trigger actions.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<ButtonSnippet story="Variants" />}
|
||||
code={`<Inline alignY="center">
|
||||
<Button iconStart="cloud" variant="primary">
|
||||
Button
|
||||
</Button>
|
||||
<Button iconStart="cloud" variant="secondary">
|
||||
Button
|
||||
</Button>
|
||||
<Button iconStart="cloud" variant="tertiary">
|
||||
Button
|
||||
</Button>
|
||||
</Inline>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Button } from '@backstage/canon';
|
||||
|
||||
<Button />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
<CodeBlock
|
||||
code={`<Button className="button" />`}
|
||||
/>
|
||||
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={buttonPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
|
||||
Here's a view when buttons have different variants.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<ButtonSnippet story="Variants" />}
|
||||
code={buttonVariants}
|
||||
/>
|
||||
|
||||
### Sizes
|
||||
|
||||
Here's a view when buttons have different sizes.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<ButtonSnippet story="Sizes" />}
|
||||
code={`<Inline alignY="center">
|
||||
<Button size="small">Small</Button>
|
||||
<Button size="medium">Medium</Button>
|
||||
</Inline>`}
|
||||
/>
|
||||
|
||||
### With Icons
|
||||
|
||||
Here's a view when buttons have icons.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<ButtonSnippet story="WithIcons" />}
|
||||
code={`<Inline alignY="center">
|
||||
<Button iconStart="cloud">Button</Button>
|
||||
<Button iconEnd="chevronRight">Button</Button>
|
||||
<Button iconStart="cloud" iconEnd="chevronRight">Button</Button>
|
||||
</Inline>`}
|
||||
/>
|
||||
|
||||
### Full width
|
||||
|
||||
Here's a view when buttons are full width.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<ButtonSnippet story="FullWidth" />}
|
||||
code={`<Flex style={{ width: '300px' }}>
|
||||
<Button fullWidth>Full width</Button>
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Disabled
|
||||
|
||||
Here's a view when buttons are disabled.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<ButtonSnippet story="Disabled" />}
|
||||
code={`<Button disabled>Button</Button>`}
|
||||
/>
|
||||
|
||||
### Responsive
|
||||
|
||||
Here's a view when buttons are responsive.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Button variant={{ initial: 'primary', lg: 'secondary' }}>
|
||||
Responsive Button
|
||||
</Button>`}
|
||||
/>
|
||||
@@ -1,19 +0,0 @@
|
||||
import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const buttonPropDefs: Record<string, PropDef> = {
|
||||
variant: {
|
||||
type: 'enum',
|
||||
values: ['primary', 'secondary'],
|
||||
default: 'primary',
|
||||
responsive: true,
|
||||
},
|
||||
size: {
|
||||
type: 'enum',
|
||||
values: ['small', 'medium'],
|
||||
default: 'medium',
|
||||
responsive: true,
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,66 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { CheckboxSnippet } from '@/snippets/stories-snippets';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { BaseUI } from '@/components/HeadlessBanners/BaseUI';
|
||||
import { checkboxPropDefs } from './props';
|
||||
|
||||
# Checkbox
|
||||
|
||||
A checkbox component that can be used to trigger actions.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<CheckboxSnippet story="Default" />}
|
||||
code={`<Checkbox label="Accept terms and conditions" />`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Checkbox } from '@backstage/canon';
|
||||
|
||||
<Checkbox />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
<CodeBlock
|
||||
code={`<Checkbox className="checkbox" />`}
|
||||
/>
|
||||
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<BaseUI href="https://base-ui.com/react/components/checkbox" />
|
||||
|
||||
<PropsTable data={checkboxPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### All variants
|
||||
|
||||
Here's a view when checkboxes have different variants.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<CheckboxSnippet story="AllVariants" />}
|
||||
code={`<Inline alignY="center">
|
||||
<Checkbox />
|
||||
<Checkbox checked />
|
||||
<Checkbox label="Checkbox" />
|
||||
<Checkbox label="Checkbox" checked />
|
||||
</Inline>`}
|
||||
/>
|
||||
@@ -1,113 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { CollapsibleSnippet } from '@/snippets/stories-snippets';
|
||||
import {
|
||||
collapsibleRootPropDefs,
|
||||
collapsibleTriggerPropDefs,
|
||||
collapsiblePanelPropDefs,
|
||||
} from './props';
|
||||
|
||||
# Collapsible
|
||||
|
||||
An avatar component with a fallback for initials.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
height={240}
|
||||
preview={<CollapsibleSnippet story="Default" />}
|
||||
code={`<Collapsible.Root>
|
||||
<Collapsible.Trigger render={(props, state) => (
|
||||
<Button {...props}>
|
||||
{state.open ? 'Close Panel' : 'Open Panel'}
|
||||
</Button>
|
||||
)} />
|
||||
<Collapsible.Panel>
|
||||
<Box>
|
||||
<Text>It's the edge of the world and all of Western civilization</Text>
|
||||
<Text>The sun may rise in the East, at least it settled in a final location</Text>
|
||||
<Text>It's understood that Hollywood sells Californication</Text>
|
||||
</Box>
|
||||
</Collapsible.Panel>
|
||||
</Collapsible.Root>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Collapsible } from '@backstage/canon';
|
||||
|
||||
<Collapsible.Root>
|
||||
<Collapsible.Trigger render={(props, state) => (
|
||||
<Button {...props}>
|
||||
{state.open ? 'Close Panel' : 'Open Panel'}
|
||||
</Button>
|
||||
)} />
|
||||
<Collapsible.Panel>Your content</Collapsible.Panel>
|
||||
</Collapsible.Root>`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
- `canon-CollapsibleRoot`
|
||||
- `canon-CollapsibleTrigger`
|
||||
- `canon-CollapsiblePanel`
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
### Collapsible.Root
|
||||
|
||||
Groups all parts of the collapsible. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={collapsibleRootPropDefs} />
|
||||
|
||||
### Collapsible.Trigger
|
||||
|
||||
The trigger by default render a simple unstyled button. Because menus can be rendered in different ways, we recommend
|
||||
using the `render` prop to render a custom trigger.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Collapsible.Trigger render={props => <Button {...props} />} />`}
|
||||
/>
|
||||
|
||||
<PropsTable data={collapsibleTriggerPropDefs} />
|
||||
|
||||
### Collapsible.Panel
|
||||
|
||||
A panel with the collapsible contents. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={collapsiblePanelPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
Open the panel by default by setting the `defaultOpen` prop to `true`.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<CollapsibleSnippet story="Open" />}
|
||||
code={`<Collapsible.Root defaultOpen>
|
||||
<Collapsible.Trigger render={(props, state) => (
|
||||
<Button {...props}>
|
||||
{state.open ? 'Close Panel' : 'Open Panel'}
|
||||
</Button>
|
||||
)} />
|
||||
<Collapsible.Panel>
|
||||
<Box>
|
||||
<Text>It's the edge of the world and all of Western civilization</Text>
|
||||
<Text>The sun may rise in the East, at least it settled in a final location</Text>
|
||||
<Text>It's understood that Hollywood sells Californication</Text>
|
||||
</Box>
|
||||
</Collapsible.Panel>
|
||||
</Collapsible.Root>`}
|
||||
/>
|
||||
@@ -1,43 +0,0 @@
|
||||
import {
|
||||
classNamePropDefs,
|
||||
stylePropDefs,
|
||||
renderPropDefs,
|
||||
} from '@/utils/propDefs';
|
||||
import type { PropDef } from '@/utils/propDefs';
|
||||
|
||||
export const collapsibleRootPropDefs: Record<string, PropDef> = {
|
||||
defaultOpen: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
open: {
|
||||
type: 'boolean',
|
||||
},
|
||||
onOpenChange: {
|
||||
type: 'enum',
|
||||
values: ['(open) => void'],
|
||||
},
|
||||
...renderPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
|
||||
export const collapsibleTriggerPropDefs: Record<string, PropDef> = {
|
||||
...renderPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
|
||||
export const collapsiblePanelPropDefs: Record<string, PropDef> = {
|
||||
hiddenUntilFound: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
keepMounted: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
...renderPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
import {
|
||||
classNamePropDefs,
|
||||
stylePropDefs,
|
||||
gapPropDefs,
|
||||
} from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const containerPropDefs: Record<string, PropDef> = {
|
||||
...gapPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,83 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import {
|
||||
flexFAQ1,
|
||||
flexSimple,
|
||||
flexResponsive,
|
||||
flexAlign,
|
||||
} from '@/snippets/code-snippets';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { FlexSnippet } from '@/snippets/stories-snippets';
|
||||
import { flexPropDefs } from './props';
|
||||
import { spacingPropDefs } from '../../../../utils/propDefs';
|
||||
|
||||
# Flex
|
||||
|
||||
This is the flex container component. It will help to define the number of
|
||||
columns that will be used in the grid. You can also define the gap between the
|
||||
columns. All values are responsive.
|
||||
|
||||
<Snippet
|
||||
py={4}
|
||||
align="center"
|
||||
preview={<FlexSnippet story="Default" />}
|
||||
code={`<Flex>
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
<DecorativeBox />
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Flex } from '@backstage/canon';
|
||||
|
||||
<Flex />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={flexPropDefs} />
|
||||
|
||||
The grid component also accepts all the spacing props from the Box component.
|
||||
|
||||
<PropsTable data={spacingPropDefs} />
|
||||
|
||||
## Common questions
|
||||
|
||||
### Can I stack horizontally?
|
||||
|
||||
The Flex component only allows for stacking elements vertically. If you want
|
||||
to create a column layout, please use the Grid component.
|
||||
|
||||
<CodeBlock code={flexFAQ1} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple
|
||||
|
||||
A simple example of how to use the Flex component.
|
||||
|
||||
<CodeBlock code={flexSimple} />
|
||||
|
||||
### Responsive
|
||||
|
||||
The Flex component also supports responsive values, making it easy to create
|
||||
responsive designs.
|
||||
|
||||
<CodeBlock code={flexResponsive} />
|
||||
|
||||
### Align
|
||||
|
||||
The Flex component also supports responsive alignment, making it easy to
|
||||
create responsive designs.
|
||||
|
||||
<CodeBlock code={flexAlign} />
|
||||
@@ -1,27 +0,0 @@
|
||||
import {
|
||||
PropDef,
|
||||
childrenPropDefs,
|
||||
classNamePropDefs,
|
||||
stylePropDefs,
|
||||
} from '../../../../utils/propDefs';
|
||||
|
||||
export const flexPropDefs: Record<string, PropDef> = {
|
||||
align: {
|
||||
type: 'enum',
|
||||
values: ['start', 'center', 'end', 'baseline', 'stretch'],
|
||||
responsive: true,
|
||||
},
|
||||
direction: {
|
||||
type: 'enum',
|
||||
values: ['row', 'column', 'row-reverse', 'column-reverse'],
|
||||
responsive: true,
|
||||
},
|
||||
justify: {
|
||||
type: 'enum',
|
||||
values: ['start', 'center', 'end', 'between'],
|
||||
responsive: true,
|
||||
},
|
||||
...childrenPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
import {
|
||||
PropDef,
|
||||
childrenPropDefs,
|
||||
classNamePropDefs,
|
||||
stylePropDefs,
|
||||
} from '../../../../utils/propDefs';
|
||||
|
||||
const columnsValues = [
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'10',
|
||||
'11',
|
||||
'12',
|
||||
];
|
||||
|
||||
export const gridPropDefs: Record<string, PropDef> = {
|
||||
columns: {
|
||||
type: 'enum | string',
|
||||
values: [...columnsValues, 'auto'],
|
||||
responsive: true,
|
||||
default: 'auto',
|
||||
},
|
||||
...childrenPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
|
||||
export const gridItemPropDefs: Record<string, PropDef> = {
|
||||
colSpan: {
|
||||
type: 'enum | string',
|
||||
values: [...columnsValues, 'full'],
|
||||
responsive: true,
|
||||
},
|
||||
rowSpan: {
|
||||
type: 'enum | string',
|
||||
values: [...columnsValues, 'full'],
|
||||
responsive: true,
|
||||
},
|
||||
start: {
|
||||
type: 'enum | string',
|
||||
values: [...columnsValues, 'auto'],
|
||||
responsive: true,
|
||||
},
|
||||
end: {
|
||||
type: 'enum | string',
|
||||
values: [...columnsValues, 'auto'],
|
||||
responsive: true,
|
||||
},
|
||||
...childrenPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,90 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { HeadingSnippet } from '@/snippets/stories-snippets';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { headingPropDefs } from './props';
|
||||
|
||||
# Heading
|
||||
|
||||
Headings are used to structure the content of your page.
|
||||
|
||||
<Snippet
|
||||
py={4}
|
||||
preview={<HeadingSnippet story="Title1" />}
|
||||
code={`<Heading variant="title1">Hello World!</Heading>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Heading } from '@backstage/canon';
|
||||
|
||||
<Heading />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
<CodeBlock
|
||||
code={`<Heading className="heading" />`}
|
||||
/>
|
||||
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={headingPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### All variants
|
||||
|
||||
The `Heading` component has a `variant` prop that can be used to change the
|
||||
appearance of the heading.
|
||||
|
||||
<Snippet
|
||||
py={2}
|
||||
open
|
||||
preview={<HeadingSnippet story="AllVariants" />}
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<Heading variant="display">Display</Heading>
|
||||
<Heading variant="title1">Title 1</Heading>
|
||||
<Heading variant="title2">Title 2</Heading>
|
||||
<Heading variant="title3">Title 3</Heading>
|
||||
<Heading variant="title4">Title 4</Heading>
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Truncate
|
||||
|
||||
The `Heading` component has a `truncate` prop that can be used to truncate the
|
||||
heading.
|
||||
|
||||
<Snippet
|
||||
py={2}
|
||||
open
|
||||
preview={<HeadingSnippet story="Truncate" />}
|
||||
code={`<Heading style={{ maxWidth: '400px' }} truncate>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Heading>`}
|
||||
/>
|
||||
|
||||
### Responsive
|
||||
|
||||
You can also use the `variant` prop to change the appearance of the text based
|
||||
on the screen size.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Heading variant={{ initial: 'title2', lg: 'title1' }}>
|
||||
Responsive heading
|
||||
</Heading>`}
|
||||
/>
|
||||
@@ -1,21 +0,0 @@
|
||||
import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const headingPropDefs: Record<string, PropDef> = {
|
||||
variant: {
|
||||
type: 'enum',
|
||||
values: ['display', 'title1', 'title2', 'title3', 'title4', 'title5'],
|
||||
responsive: true,
|
||||
},
|
||||
children: {
|
||||
type: 'enum',
|
||||
values: ['ReactNode'],
|
||||
responsive: false,
|
||||
},
|
||||
truncate: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,97 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { IconButtonSnippet } from '@/snippets/stories-snippets';
|
||||
import { iconButtonVariants } from '@/snippets/code-snippets';
|
||||
import { iconButtonPropDefs } from './props';
|
||||
|
||||
# Icon Button
|
||||
|
||||
A button component with a single icon that can be used to trigger actions.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<IconButtonSnippet story="Variants" />}
|
||||
code={`<Flex align="center">
|
||||
<IconButton icon="cloud" variant="primary" />
|
||||
<IconButton icon="cloud" variant="secondary" />
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { IconButton } from '@backstage/canon';
|
||||
|
||||
<IconButton />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
<CodeBlock
|
||||
code={`<IconButton className="canon-IconButton" />`}
|
||||
/>
|
||||
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={iconButtonPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
|
||||
Here's a view when buttons have different variants.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<IconButtonSnippet story="Variants" />}
|
||||
code={iconButtonVariants}
|
||||
/>
|
||||
|
||||
### Sizes
|
||||
|
||||
Here's a view when buttons have different sizes.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<IconButtonSnippet story="Sizes" />}
|
||||
code={`<Flex align="center">
|
||||
<IconButton icon="cloud" size="small" />
|
||||
<IconButton icon="cloud" size="medium" />
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Disabled
|
||||
|
||||
Here's a view when buttons are disabled.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<IconButtonSnippet story="Disabled" />}
|
||||
code={`<IconButton icon="cloud" disabled />`}
|
||||
/>
|
||||
|
||||
### Responsive
|
||||
|
||||
Here's a view when buttons are responsive.
|
||||
|
||||
<CodeBlock
|
||||
code={`<IconButton icon="cloud" variant={{ initial: 'primary', lg: 'secondary' }} />`}
|
||||
/>
|
||||
@@ -1,20 +0,0 @@
|
||||
import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const iconButtonPropDefs: Record<string, PropDef> = {
|
||||
variant: {
|
||||
type: 'enum',
|
||||
values: ['primary', 'secondary'],
|
||||
default: 'primary',
|
||||
responsive: true,
|
||||
},
|
||||
size: {
|
||||
type: 'enum',
|
||||
values: ['small', 'medium'],
|
||||
default: 'medium',
|
||||
responsive: true,
|
||||
},
|
||||
icon: { type: 'enum', values: 'icon', responsive: false },
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { IconSnippet } from '@/snippets/stories-snippets';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { iconPropDefs } from './props';
|
||||
|
||||
# Icon
|
||||
|
||||
Icons are used to represent an action or a state.
|
||||
|
||||
<Snippet
|
||||
py={4}
|
||||
align="center"
|
||||
preview={<IconSnippet story="Default" />}
|
||||
code={`<Icon name="heart" />`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Icon } from '@backstage/canon';
|
||||
|
||||
<Icon />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
<CodeBlock
|
||||
code={`<Icon className="icon" />`}
|
||||
/>
|
||||
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={iconPropDefs} />
|
||||
@@ -1,84 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import {
|
||||
MenuSnippet,
|
||||
ButtonSnippet,
|
||||
LinkSnippet,
|
||||
} from '@/snippets/stories-snippets';
|
||||
import { linkPropDefs } from './props';
|
||||
|
||||
# Link
|
||||
|
||||
A link component that renders a `<a>` element.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<LinkSnippet story="Default" />}
|
||||
code={`<Link href="https://backstage.io">Sign up for Backstage</Link>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Link } from '@backstage/canon';
|
||||
|
||||
<Link href="https://backstage.io">Sign up for Backstage</Link>`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
- `canon-Link`
|
||||
- `canon-Link[data-variant='body']`
|
||||
- `canon-Link[data-variant='subtitle']`
|
||||
- `canon-Link[data-variant='caption']`
|
||||
- `canon-Link[data-variant='label']`
|
||||
- `canon-Link[data-weight='regular']`
|
||||
- `canon-Link[data-weight='bold']`
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={linkPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
|
||||
Here's a view when links have different variants.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<LinkSnippet story="AllVariants" />}
|
||||
code={`<Flex gap="4" direction="column">
|
||||
<Link href="https://canon.backstage.io" variant="subtitle" />
|
||||
<Link href="https://canon.backstage.io" variant="body" />
|
||||
<Link href="https://canon.backstage.io" variant="caption" />
|
||||
<Link href="https://canon.backstage.io" variant="label" />
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Weights
|
||||
|
||||
Here's a view when links have different weights.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<LinkSnippet story="AllWeights" />}
|
||||
code={`<Flex gap="4" direction="column">
|
||||
<Link href="https://canon.backstage.io" weight="regular" />
|
||||
<Link href="https://canon.backstage.io" weight="bold" />
|
||||
</Flex>`}
|
||||
/>
|
||||
@@ -1,22 +0,0 @@
|
||||
import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs';
|
||||
import type { PropDef } from '@/utils/propDefs';
|
||||
|
||||
export const linkPropDefs: Record<string, PropDef> = {
|
||||
to: {
|
||||
type: 'string',
|
||||
},
|
||||
variant: {
|
||||
type: 'enum',
|
||||
values: ['subtitle', 'body', 'caption', 'label'],
|
||||
default: 'body',
|
||||
responsive: true,
|
||||
},
|
||||
weight: {
|
||||
type: 'enum',
|
||||
values: ['regular', 'bold'],
|
||||
default: 'regular',
|
||||
responsive: true,
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,202 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { MenuSnippet } from '@/snippets/stories-snippets';
|
||||
import { BaseUI } from '@/components/HeadlessBanners/BaseUI';
|
||||
import {
|
||||
menuRootPropDefs,
|
||||
menuTriggerPropDefs,
|
||||
menuPositionerPropDefs,
|
||||
menuItemPropDefs,
|
||||
} from './props';
|
||||
|
||||
# Menu
|
||||
|
||||
A list of actions in a dropdown, enhanced with keyboard navigation.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<MenuSnippet story="Default" />}
|
||||
code={`<Menu.Root>
|
||||
<Menu.Trigger
|
||||
render={props => (
|
||||
<Button
|
||||
{...props}
|
||||
size="medium"
|
||||
variant="secondary"
|
||||
iconEnd="chevron-down"
|
||||
>
|
||||
Menu
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner sideOffset={8} align="start">
|
||||
<Menu.Popup>
|
||||
<Menu.Item>Settings</Menu.Item>
|
||||
<Menu.Item>Invite new members</Menu.Item>
|
||||
<Menu.Item>Download app</Menu.Item>
|
||||
<Menu.Item>Log out</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Menu } from '@backstage/canon';
|
||||
|
||||
<Menu.Root>
|
||||
<Menu.Trigger />
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner>
|
||||
<Menu.Popup>
|
||||
<Menu.Item />
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
- `canon-MenuTrigger`
|
||||
- `canon-MenuBackdrop`
|
||||
- `canon-MenuPositioner`
|
||||
- `canon-MenuPopup`
|
||||
- `canon-MenuArrow`
|
||||
- `canon-MenuItem`
|
||||
- `canon-MenuGroup`
|
||||
- `canon-MenuGroupLabel`
|
||||
- `canon-MenuRadioGroup`
|
||||
- `canon-MenuRadioItem`
|
||||
- `canon-MenuRadioItemIndicator`
|
||||
- `canon-MenuCheckboxItem`
|
||||
- `canon-MenuCheckboxItemIndicator`
|
||||
- `canon-MenuSubmenuTrigger`
|
||||
- `canon-MenuSeparator`
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<BaseUI href="https://base-ui.com/react/components/menu" />
|
||||
|
||||
### Menu.Root
|
||||
|
||||
Groups all parts of the menu. Doesn't render its own HTML element.
|
||||
|
||||
<PropsTable data={menuRootPropDefs} />
|
||||
|
||||
### Menu.Trigger
|
||||
|
||||
The trigger by default render a simple unstyled button. Because menus can be rendered in different ways, we recommend
|
||||
using the `render` prop to render a custom trigger.
|
||||
|
||||
<CodeBlock code={`<Menu.Trigger render={props => <Button {...props} />} />`} />
|
||||
|
||||
<PropsTable data={menuTriggerPropDefs} />
|
||||
|
||||
### Menu.Positioner
|
||||
|
||||
Positions the menu popup against the trigger. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={menuPositionerPropDefs} />
|
||||
|
||||
### Menu.Item
|
||||
|
||||
An individual interactive item in the menu. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={menuItemPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Open on hover
|
||||
|
||||
To create a menu that opens on hover, add the `openOnHover` prop to the Root part.
|
||||
You can additionally configure how quickly the menu opens on hover using the `delay` prop.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<MenuSnippet story="OpenOnHover" />}
|
||||
code={`<Menu.Root openOnHover delay={100}>
|
||||
<Menu.Trigger
|
||||
render={props => (
|
||||
<Button
|
||||
{...props}
|
||||
size="medium"
|
||||
variant="secondary"
|
||||
iconEnd="chevron-down"
|
||||
>
|
||||
Menu
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner sideOffset={8} align="start">
|
||||
<Menu.Popup>
|
||||
<Menu.Item>Settings</Menu.Item>
|
||||
<Menu.Item>Invite new members</Menu.Item>
|
||||
<Menu.Item>Download app</Menu.Item>
|
||||
<Menu.Item>Log out</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>`}
|
||||
/>
|
||||
|
||||
### Nested navigation
|
||||
|
||||
You can nest menus to create a more complex navigation structure.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<MenuSnippet story="Submenu" />}
|
||||
code={`<Menu.Trigger
|
||||
render={props => (
|
||||
<Button
|
||||
{...props}
|
||||
size="small"
|
||||
variant="secondary"
|
||||
iconEnd={<Icon name="chevron-down" />}
|
||||
>
|
||||
Menu
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner sideOffset={8} align="start">
|
||||
<Menu.Popup>
|
||||
<Menu.Item>Settings</Menu.Item>
|
||||
<Menu.Item>Invite new members</Menu.Item>
|
||||
<Menu.Item>Download app</Menu.Item>
|
||||
<Menu.Item>Log out</Menu.Item>
|
||||
<Menu.Root>
|
||||
<Menu.SubmenuTrigger>Submenu</Menu.SubmenuTrigger>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner>
|
||||
<Menu.Popup>
|
||||
<Menu.Item>Submenu Item 1</Menu.Item>
|
||||
<Menu.Item>Submenu Item 2</Menu.Item>
|
||||
<Menu.Item>Submenu Item 3</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>`}
|
||||
/>
|
||||
@@ -1,128 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { SelectSnippet } from '@/snippets/stories-snippets';
|
||||
import { selectPropDefs } from './props';
|
||||
|
||||
# Select
|
||||
|
||||
A common form component for choosing a predefined value in a dropdown menu.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<SelectSnippet story="Preview" />}
|
||||
code={`<Select name="font" label="Font Family" options={[
|
||||
{ value: 'sans', label: 'Sans-serif' },
|
||||
{ value: 'serif', label: 'Serif' },
|
||||
{ value: 'mono', label: 'Monospace' },
|
||||
{ value: 'cursive', label: 'Cursive' },
|
||||
]} />
|
||||
`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Select } from '@backstage/canon';
|
||||
|
||||
<Select
|
||||
name="font"
|
||||
options={[
|
||||
{ value: 'sans', label: 'Sans-serif' },
|
||||
{ value: 'serif', label: 'Serif' },
|
||||
{ value: 'mono', label: 'Monospace' },
|
||||
{ value: 'cursive', label: 'Cursive' },
|
||||
]}
|
||||
/>
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
<CodeBlock
|
||||
code={`<Select className="canon-SelectFieldRoot" />`}
|
||||
/>
|
||||
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={selectPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### With Label and description
|
||||
|
||||
Select component with label and description.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<SelectSnippet story="WithDescription" />}
|
||||
code={`<Select
|
||||
name="font"
|
||||
label="Font Family"
|
||||
description="Choose a font family for your document"
|
||||
options={[ ... ]}
|
||||
/>`}
|
||||
/>
|
||||
|
||||
### Sizes
|
||||
|
||||
Here's a view when the selects have different sizes.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<SelectSnippet story="Sizes" />}
|
||||
code={`<Flex>
|
||||
<Select
|
||||
size="small"
|
||||
label="Font family"
|
||||
options={[ ... ]}
|
||||
/>
|
||||
<Select
|
||||
size="medium"
|
||||
label="Font family"
|
||||
options={[ ... ]}
|
||||
/>
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Disabled
|
||||
|
||||
Here's a view when the select is disabled.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<SelectSnippet story="Disabled" />}
|
||||
code={`<Select
|
||||
disabled
|
||||
label="Font family"
|
||||
options={[ ... ]}
|
||||
/>`}
|
||||
/>
|
||||
|
||||
### Responsive
|
||||
|
||||
Here's a view when the select is responsive.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Select
|
||||
size={{ initial: 'small', lg: 'medium' }}
|
||||
label="Font family"
|
||||
options={[ ... ]}
|
||||
/>`}
|
||||
/>
|
||||
@@ -1,54 +0,0 @@
|
||||
import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const selectPropDefs: Record<string, PropDef> = {
|
||||
label: {
|
||||
type: 'string',
|
||||
default: 'Select an option',
|
||||
responsive: false,
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
required: true,
|
||||
},
|
||||
options: {
|
||||
type: 'enum',
|
||||
values: ['Array<{ value: string, label: string }>'],
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
defaultValue: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
placeholder: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
size: {
|
||||
type: 'enum',
|
||||
values: ['small', 'medium'],
|
||||
default: 'medium',
|
||||
responsive: true,
|
||||
},
|
||||
onValueChange: {
|
||||
type: 'enum',
|
||||
values: ['(value: string) => void'],
|
||||
responsive: false,
|
||||
},
|
||||
onOpenChange: {
|
||||
type: 'enum',
|
||||
values: ['(open: boolean) => void'],
|
||||
responsive: false,
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,92 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { TabsSnippet } from '@/snippets/stories-snippets';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import {
|
||||
tabsRootPropDefs,
|
||||
tabsListPropDefs,
|
||||
tabsTabPropDefs,
|
||||
tabsPanelPropDefs,
|
||||
} from './props';
|
||||
import { BaseUI } from '@/components/HeadlessBanners/BaseUI';
|
||||
|
||||
# Tabs
|
||||
|
||||
A component for toggling between related panels on the same page.
|
||||
|
||||
<Snippet
|
||||
py={4}
|
||||
preview={<TabsSnippet story="Default" />}
|
||||
code={`<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Tab 1</Tabs.Tab>
|
||||
<Tabs.Tab>Tab 2</Tabs.Tab>
|
||||
<Tabs.Tab>Tab 3 With long title</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>Content for Tab 1</Tabs.Panel>
|
||||
<Tabs.Panel>Content for Tab 2</Tabs.Panel>
|
||||
<Tabs.Panel>Content for Tab 3</Tabs.Panel>
|
||||
</Tabs.Root>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Tabs } from '@backstage/canon';
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Tab 1</Tabs.Tab>
|
||||
<Tabs.Tab>Tab 2</Tabs.Tab>
|
||||
<Tabs.Tab>Tab 3</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>Content for Tab 1</Tabs.Panel>
|
||||
<Tabs.Panel>Content for Tab 2</Tabs.Panel>
|
||||
<Tabs.Panel>Content for Tab 3</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
- `canon-TabsRoot`
|
||||
- `canon-TabsList`
|
||||
- `canon-TabsTab`
|
||||
- `canon-TabsPanel`
|
||||
- `canon-TabsIndicator`
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<BaseUI href="https://base-ui.com/react/components/menu" />
|
||||
|
||||
### Tabs.Root
|
||||
|
||||
Groups the tabs and the corresponding panels. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={tabsRootPropDefs} />
|
||||
|
||||
### Tabs.List
|
||||
|
||||
Groups the individual tab buttons. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={tabsListPropDefs} />
|
||||
|
||||
### Tabs.Tab
|
||||
|
||||
An individual interactive tab button that toggles the corresponding panel. Renders a `<button>` element.
|
||||
|
||||
<PropsTable data={tabsTabPropDefs} />
|
||||
|
||||
### Tabs.Panel
|
||||
|
||||
A panel displayed when the corresponding tab is active. Renders a `<div>` element.
|
||||
|
||||
<PropsTable data={tabsPanelPropDefs} />
|
||||
@@ -1,80 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { TextFieldSnippet } from '@/snippets/stories-snippets';
|
||||
import { BaseUI } from '@/components/HeadlessBanners/BaseUI';
|
||||
import { inputPropDefs } from './props';
|
||||
|
||||
# TextField
|
||||
|
||||
A text field component for your forms.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
preview={<TextFieldSnippet story="WithLabel" />}
|
||||
code={`<TextField label="Label" placeholder="Enter a URL" />`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { TextField } from '@backstage/canon';
|
||||
|
||||
<TextField />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
- `canon-TextField`
|
||||
- `canon-TextFieldLabel`
|
||||
- `canon-TextFieldRequired`
|
||||
- `canon-TextFieldInputWrapper`
|
||||
- `canon-TextFieldIcon`
|
||||
- `canon-TextFieldInput`
|
||||
- `canon-TextFieldClearButton`
|
||||
- `canon-TextFieldClearButtonIcon`
|
||||
- `canon-TextFieldDescription`
|
||||
- `canon-TextFieldError`
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={inputPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### Sizes
|
||||
|
||||
We support two different sizes: `small`, `medium`.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<TextFieldSnippet story="Sizes" />}
|
||||
code={`<Flex direction="row" gap="4">
|
||||
<TextField size="small" placeholder="Small" icon={<Icon name="sparkling" />} />
|
||||
<TextField size="medium" placeholder="Medium" icon={<Icon name="sparkling" />} />
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### With description
|
||||
|
||||
Here's a simple TextField with a description.
|
||||
|
||||
<Snippet
|
||||
align="center"
|
||||
py={4}
|
||||
open
|
||||
preview={<TextFieldSnippet story="WithDescription" />}
|
||||
code={`<TextField label="Label" description="Description" placeholder="Enter a URL" />`}
|
||||
/>
|
||||
@@ -1,27 +0,0 @@
|
||||
import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const inputPropDefs: Record<string, PropDef> = {
|
||||
size: {
|
||||
type: 'enum',
|
||||
values: ['small', 'medium'],
|
||||
default: 'small',
|
||||
responsive: true,
|
||||
},
|
||||
label: {
|
||||
type: 'string',
|
||||
},
|
||||
icon: {
|
||||
type: 'enum',
|
||||
values: ['ReactNode'],
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,129 +0,0 @@
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { TextSnippet } from '@/snippets/stories-snippets';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { textPropDefs } from './props';
|
||||
|
||||
# Text
|
||||
|
||||
The `Text` component is used to display content on your page.
|
||||
|
||||
<Snippet
|
||||
py={4}
|
||||
preview={<TextSnippet story="Default" />}
|
||||
code={`<Text style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is in
|
||||
the painting?
|
||||
</Text>`}
|
||||
/>
|
||||
|
||||
<Tabs.Root>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab>Usage</Tabs.Tab>
|
||||
<Tabs.Tab>Theming</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel>
|
||||
<CodeBlock
|
||||
code={`import { Text } from '@backstage/canon';
|
||||
|
||||
<Text />
|
||||
`}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel>
|
||||
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
|
||||
your brand. For additional flexibility, you can use the provided class names for each element listed below.
|
||||
<CodeBlock
|
||||
code={`<Text className="text" />`}
|
||||
/>
|
||||
|
||||
</Tabs.Panel>
|
||||
</Tabs.Root>
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable data={textPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
### All variants
|
||||
|
||||
The `Text` component has a `variant` prop that can be used to change the
|
||||
appearance of the text.
|
||||
|
||||
<Snippet
|
||||
open
|
||||
preview={<TextSnippet story="AllVariants" />}
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<Text variant="subtitle" style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
<Text variant="body" style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
<Text variant="caption" style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
<Text variant="label" style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### All weights
|
||||
|
||||
The `Text` component has a `weight` prop that can be used to change the
|
||||
appearance of the text.
|
||||
|
||||
<Snippet
|
||||
open
|
||||
preview={<TextSnippet story="AllWeights" />}
|
||||
code={`<Flex direction="column" gap="4">
|
||||
<Text weight="regular" style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
<Text weight="bold" style={{ maxWidth: '600px' }}>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>
|
||||
</Flex>`}
|
||||
/>
|
||||
|
||||
### Truncate
|
||||
|
||||
The `Text` component has a `truncate` prop that can be used to truncate the
|
||||
text.
|
||||
|
||||
<Snippet
|
||||
open
|
||||
preview={<TextSnippet story="Truncate" />}
|
||||
code={`<Text weight="regular" style={{ maxWidth: '600px' }} truncate>
|
||||
A man looks at a painting in a museum and says, “Brothers and sisters I
|
||||
have none, but that man's father is my father's son.” Who is
|
||||
in the painting?
|
||||
</Text>`}
|
||||
/>
|
||||
|
||||
### Responsive
|
||||
|
||||
You can also use the `variant` prop to change the appearance of the text based
|
||||
on the screen size.
|
||||
|
||||
<CodeBlock
|
||||
code={`<Text variant={{ initial: 'body', lg: 'subtitle' }}>
|
||||
Responsive text
|
||||
</Text>`}
|
||||
/>
|
||||
@@ -1,26 +0,0 @@
|
||||
import {
|
||||
childrenPropDefs,
|
||||
classNamePropDefs,
|
||||
stylePropDefs,
|
||||
} from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const textPropDefs: Record<string, PropDef> = {
|
||||
variant: {
|
||||
type: 'enum',
|
||||
values: ['display', 'title1', 'title2', 'title3', 'title4', 'title5'],
|
||||
responsive: true,
|
||||
},
|
||||
weight: {
|
||||
type: 'enum',
|
||||
values: ['regular', 'bold'],
|
||||
responsive: true,
|
||||
},
|
||||
truncate: {
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
},
|
||||
...childrenPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
# Releases
|
||||
|
||||
## Version 0.3.0
|
||||
|
||||
### Main updates
|
||||
|
||||
- Add `DataTable` component - ([#29484](https://github.com/backstage/backstage/pull/29484), [#29603](https://github.com/backstage/backstage/pull/29603))
|
||||
- Add `Select` component - ([#29440](https://github.com/backstage/backstage/pull/29440))
|
||||
- Add `Avatar` component - ([#29594](https://github.com/backstage/backstage/pull/29594))
|
||||
- Add `Collapsible` component - ([#29617](https://github.com/backstage/backstage/pull/29617))
|
||||
- Add `TextField` component instead of `Field` + `Input` - ([#29364](https://github.com/backstage/backstage/pull/29364))
|
||||
- Add `TableCellProfile` - ([#29600](https://github.com/backstage/backstage/pull/29600))
|
||||
- Add breakpoint hooks - `up()` and `down()` - ([#29564](https://github.com/backstage/backstage/pull/29564))
|
||||
- Add gray scale css tokens - ([#29543](https://github.com/backstage/backstage/pull/29543))
|
||||
- Update CSS styling API using `[data-___]` instead of class names for props - ([#29560](https://github.com/backstage/backstage/pull/29560))
|
||||
- Update `Checkbox` dark mode - ([#29544](https://github.com/backstage/backstage/pull/29544))
|
||||
- Update `Container` styles - ([#29475](https://github.com/backstage/backstage/pull/29475))
|
||||
- Update `Menu` styles - ([#29351](https://github.com/backstage/backstage/pull/29351))
|
||||
- Fix `Select` styles on small sizes + with long option names - ([#29545](https://github.com/backstage/backstage/pull/29545))
|
||||
- Fix render prop on `Link` - ([#29247](https://github.com/backstage/backstage/pull/29247))
|
||||
- Remove `Field` from `TextField` + `Select` - ([#29482](https://github.com/backstage/backstage/pull/29482))
|
||||
- Update `textDecoration` to `none` on `Text` / `Heading` - ([#29357](https://github.com/backstage/backstage/pull/29357))
|
||||
|
||||
### Notable fixes
|
||||
|
||||
- Docs - Use stories from Storybook for all examples in Nextjs - ([#29306](https://github.com/backstage/backstage/pull/29306))
|
||||
- Docs - Add release page (this one 🤗) - ([#29461](https://github.com/backstage/backstage/pull/29461))
|
||||
- Docs - Add docs for Menu, Link - ([#29576](https://github.com/backstage/backstage/pull/29576))
|
||||
- Fix CSS watch mode - ([#29352](https://github.com/backstage/backstage/pull/29352))
|
||||
|
||||
## Version 0.2.0
|
||||
|
||||
### Main updates
|
||||
|
||||
- New `Tooltip` component ([#29241](https://github.com/backstage/backstage/pull/29241))
|
||||
- New `Menu` component. ([#29151](https://github.com/backstage/backstage/pull/29151))
|
||||
- New `IconButton` component. ([#29239](https://github.com/backstage/backstage/pull/29239))
|
||||
- New `ScrollArea` component. ([#29240](https://github.com/backstage/backstage/pull/29240))
|
||||
- Improve `Button` & `Checkbox` styles. ([#29127](https://github.com/backstage/backstage/pull/29127)) ([#28789](https://github.com/backstage/backstage/pull/28789))
|
||||
- Improve `Text` styles. ([#29200](https://github.com/backstage/backstage/pull/29200))
|
||||
- Renamed `CanonProvider` to `IconProvider`. ([#29002](https://github.com/backstage/backstage/pull/29002))
|
||||
- Added about 40+ new icons. ([#29264](https://github.com/backstage/backstage/pull/29264))
|
||||
- Simplified styling into a unique styles.css file ([#29199](https://github.com/backstage/backstage/pull/29199))
|
||||
- Added Canon styles to Backstage ([#29137](https://github.com/backstage/backstage/pull/29137))
|
||||
- Update global CSS tokens ([#28804](https://github.com/backstage/backstage/pull/28804))
|
||||
- Merge Stack + Inline into Flex ([#28634](https://github.com/backstage/backstage/pull/28634))
|
||||
|
||||
### Notable fixes:
|
||||
|
||||
- Improve `Button` types. ([#29205](https://github.com/backstage/backstage/pull/29205))
|
||||
- Move font weight and family back to each components ([#28972](https://github.com/backstage/backstage/pull/28972))
|
||||
- Fix custom values in spacing props ([#28770](https://github.com/backstage/backstage/pull/28770))
|
||||
- Multiple updates on the Canon Docs site ([#28760](https://github.com/backstage/backstage/pull/28760)) ([#28591](https://github.com/backstage/backstage/pull/28591))
|
||||
|
||||
## Version 0.1.0
|
||||
|
||||
We're excited to share the initial release of Canon 💚 In this first alpha version, you'll find the foundation of our design system:
|
||||
a set of versatile layout components and a handful of essential atomic elements to help you get started. While Canon is still in its
|
||||
early stages, it's ready for exploration and we'd love for you to give it a try and share your feedback.
|
||||
@@ -71,20 +71,17 @@ const Content = () => {
|
||||
{selectedComponents.find(c => c === 'text') && (
|
||||
<Line content={<TextSnippet story="Playground" />} title="Text" />
|
||||
)}
|
||||
{/* {selectedComponents.find(c => c === 'input') && (
|
||||
<Line content={<InputPlayground />} title="Input" />
|
||||
)} */}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const Line = ({ content, title }: { content: ReactNode; title: string }) => {
|
||||
return (
|
||||
<Grid gap={{ xs: '2', md: '4' }}>
|
||||
<Grid.Root gap={{ xs: '2', md: '4' }}>
|
||||
<Grid.Item colSpan="2">
|
||||
<Text>{title}</Text>
|
||||
</Grid.Item>
|
||||
<Grid.Item colSpan="10">{content}</Grid.Item>
|
||||
</Grid>
|
||||
</Grid.Root>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,8 +6,8 @@ import { CustomTheme } from '@/components/CustomTheme';
|
||||
import styles from '../css/page.module.css';
|
||||
|
||||
import '../css/globals.css';
|
||||
import '/public/core.css';
|
||||
import '/public/components.css';
|
||||
import '/public/theme-backstage.css';
|
||||
import '/public/theme-spotify.css';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Canon',
|
||||
|
||||
@@ -1,18 +1,3 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import styles from './styles.module.css';
|
||||
|
||||
export const Banner = ({
|
||||
|
||||
@@ -1,16 +1 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { Banner } from './Banner';
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { changelog } from '@/utils/changelog';
|
||||
import { MDXRemote } from 'next-mdx-remote-client/rsc';
|
||||
import { formattedMDXComponents } from '@/mdx-components';
|
||||
|
||||
export function Changelog() {
|
||||
// Group changelog entries by version
|
||||
const groupedChangelog = changelog.reduce((acc, entry) => {
|
||||
if (!acc[entry.version]) {
|
||||
acc[entry.version] = [];
|
||||
}
|
||||
acc[entry.version].push(entry);
|
||||
return acc;
|
||||
}, {} as Record<string, typeof changelog>);
|
||||
|
||||
// Sort versions in descending order
|
||||
const sortedVersions = Object.keys(groupedChangelog).sort((a, b) =>
|
||||
b.localeCompare(a),
|
||||
);
|
||||
|
||||
const content = sortedVersions
|
||||
.map(version => {
|
||||
const entries = groupedChangelog[version];
|
||||
|
||||
return `## Version ${version}
|
||||
|
||||
${entries
|
||||
.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}`;
|
||||
})
|
||||
.join('\n')}`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
return <MDXRemote components={formattedMDXComponents} source={content} />;
|
||||
}
|
||||
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
|
||||
@@ -1,16 +1 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { Chip } from './Chip';
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -25,7 +9,6 @@
|
||||
margin-right: 4px;
|
||||
background-color: #f0f0f0;
|
||||
color: #5d5d5d;
|
||||
transition: background-color 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.head {
|
||||
@@ -39,5 +22,5 @@
|
||||
}
|
||||
|
||||
[data-theme='dark'] .chip.head {
|
||||
background-color: #26417b;
|
||||
background-color: #33405b;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { CodeBlockProps } from '.';
|
||||
import { Text } from '../../../../packages/canon';
|
||||
import { Text } from '@backstage/canon';
|
||||
import styles from './styles.module.css';
|
||||
import parse from 'html-react-parser';
|
||||
|
||||
export const CodeBlockClient = ({
|
||||
out,
|
||||
@@ -18,7 +19,7 @@ export const CodeBlockClient = ({
|
||||
<Text variant="body">{title}</Text>
|
||||
</div>
|
||||
)}
|
||||
<div dangerouslySetInnerHTML={{ __html: out }} className={styles.code} />
|
||||
<div className={styles.code}>{parse(out)}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
position: relative;
|
||||
background: transparent;
|
||||
overflow-x: auto;
|
||||
font-family: var(--canon-font-monospace);
|
||||
font-family: var(--font-mono);
|
||||
background-color: #fff;
|
||||
transition: background-color 0.2s ease-in-out;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ReactNode, CSSProperties } from 'react';
|
||||
|
||||
export const Columns = ({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user