diff --git a/.changeset/all-camels-agree.md b/.changeset/all-camels-agree.md new file mode 100644 index 0000000000..44d8a4f2c9 --- /dev/null +++ b/.changeset/all-camels-agree.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fix broken external links in Backstage UI Header component. diff --git a/.changeset/all-parrots-change.md b/.changeset/all-parrots-change.md new file mode 100644 index 0000000000..65d5c37658 --- /dev/null +++ b/.changeset/all-parrots-change.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org': patch +--- + +Improved responsiveness of GroupProfileCard component diff --git a/.changeset/breezy-times-ring.md b/.changeset/breezy-times-ring.md new file mode 100644 index 0000000000..f65dd6ff55 --- /dev/null +++ b/.changeset/breezy-times-ring.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Updated knip-reports to detect dependencies in dev/alpha pattern diff --git a/.changeset/bright-ears-send.md b/.changeset/bright-ears-send.md new file mode 100644 index 0000000000..5104f2377b --- /dev/null +++ b/.changeset/bright-ears-send.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +Enable YAML merge keys in yamlPlaceholderResolver diff --git a/.changeset/busy-goats-create.md b/.changeset/busy-goats-create.md new file mode 100644 index 0000000000..78b8f65571 --- /dev/null +++ b/.changeset/busy-goats-create.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-search-backend-module-elasticsearch': patch +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-signals-backend': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-signals': patch +--- + +Removed/moved unused dependencies diff --git a/.changeset/clever-boats-clap.md b/.changeset/clever-boats-clap.md new file mode 100644 index 0000000000..6b40f05a76 --- /dev/null +++ b/.changeset/clever-boats-clap.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-search-react': minor +'@backstage/plugin-techdocs': minor +'@backstage/plugin-catalog': minor +'@backstage/plugin-search': minor +--- + +Add support for customizable icons in `SearchResultListItemBlueprint` and related components diff --git a/.changeset/create-app-1761312116.md b/.changeset/create-app-1761312116.md new file mode 100644 index 0000000000..b50d431d4b --- /dev/null +++ b/.changeset/create-app-1761312116.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Bumped create-app version. diff --git a/.changeset/create-app-1762897504.md b/.changeset/create-app-1762897504.md new file mode 100644 index 0000000000..b50d431d4b --- /dev/null +++ b/.changeset/create-app-1762897504.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Bumped create-app version. diff --git a/.changeset/cruel-items-dig.md b/.changeset/cruel-items-dig.md new file mode 100644 index 0000000000..65f07956ac --- /dev/null +++ b/.changeset/cruel-items-dig.md @@ -0,0 +1,27 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: Migrated Avatar component from Base UI to custom implementation with size changes: + +- Base UI-specific props are no longer supported +- Size values have been updated: + - New `x-small` size added (1.25rem / 20px) + - `small` size unchanged (1.5rem / 24px) + - `medium` size unchanged (2rem / 32px, default) + - `large` size **changed from 3rem to 2.5rem** (40px) + - New `x-large` size added (3rem / 48px) + +Migration: + +```diff +# Remove Base UI-specific props +- ++ + +# Update large size usage to x-large for same visual size +- ++ +``` + +Added `purpose` prop for accessibility control (`'informative'` or `'decoration'`). diff --git a/.changeset/cruel-plums-talk.md b/.changeset/cruel-plums-talk.md new file mode 100644 index 0000000000..bc7a30b048 --- /dev/null +++ b/.changeset/cruel-plums-talk.md @@ -0,0 +1,58 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: Migrated Checkbox component from Base UI to React Aria Components. + +API changes required: + +- `checked` → `isSelected` +- `defaultChecked` → `defaultSelected` +- `disabled` → `isDisabled` +- `required` → `isRequired` +- `label` prop removed - use `children` instead +- CSS: `bui-CheckboxLabel` class removed +- Data attribute: `data-checked` → `data-selected` +- Use without label is no longer supported + +Migration examples: + +Before: + +```tsx + +``` + +After: + +```tsx + + Accept terms + +``` + +Before: + +```tsx + +``` + +After: + +```tsx +Option +``` + +Before: + +```tsx + +``` + +After: + +```tsx + + Accessible label + +``` diff --git a/.changeset/deep-gifts-slide.md b/.changeset/deep-gifts-slide.md new file mode 100644 index 0000000000..f3be77e74d --- /dev/null +++ b/.changeset/deep-gifts-slide.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed CSS issues in Select component including popover width constraints, focus outline behavior, and overflow handling. diff --git a/.changeset/easy-hands-grow.md b/.changeset/easy-hands-grow.md new file mode 100644 index 0000000000..fc3cfd96e1 --- /dev/null +++ b/.changeset/easy-hands-grow.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend': minor +'@backstage/plugin-catalog-node': minor +--- + +Make YAML merge (<<:) support configurable in the Backstage Catalog instead of always being enabled diff --git a/.changeset/eighty-mails-leave.md b/.changeset/eighty-mails-leave.md new file mode 100644 index 0000000000..3c6ec5ab8f --- /dev/null +++ b/.changeset/eighty-mails-leave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +Allow customization of VisitList by adding optional enrichVisit, transformPathname, canSave functions to VisitsStorageApi, along with VisitDisplayProvider for colors, labels diff --git a/.changeset/eighty-results-prove.md b/.changeset/eighty-results-prove.md new file mode 100644 index 0000000000..6df2d2f11a --- /dev/null +++ b/.changeset/eighty-results-prove.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-app-visualizer': patch +--- + +Improve tree visualizer to use a horizontal layout and fill the content space. diff --git a/.changeset/eleven-carpets-win.md b/.changeset/eleven-carpets-win.md new file mode 100644 index 0000000000..69d677786a --- /dev/null +++ b/.changeset/eleven-carpets-win.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Fix a bug in the Gitlab URL reader where `search` did not handle multiple globs diff --git a/.changeset/eleven-lights-taste.md b/.changeset/eleven-lights-taste.md new file mode 100644 index 0000000000..e575b909e6 --- /dev/null +++ b/.changeset/eleven-lights-taste.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Added missing i18n diff --git a/.changeset/fancy-years-camp.md b/.changeset/fancy-years-camp.md new file mode 100644 index 0000000000..41782d4e0c --- /dev/null +++ b/.changeset/fancy-years-camp.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-notifications-backend': minor +'@backstage/plugin-notifications-common': minor +--- + +Adds support for default configuration for an entire notification channel. +This setting will also be inherited down to origins and topics while still respecting the users individual choices. + +This will be handy if you want to use a "opt-in" strategy. diff --git a/.changeset/fast-tables-sink.md b/.changeset/fast-tables-sink.md new file mode 100644 index 0000000000..a7c240fc5d --- /dev/null +++ b/.changeset/fast-tables-sink.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Improved visual consistency of PasswordField, SearchField, and MenuAutocomplete components. diff --git a/.changeset/fast-tools-mate.md b/.changeset/fast-tools-mate.md new file mode 100644 index 0000000000..2e212ce1b3 --- /dev/null +++ b/.changeset/fast-tools-mate.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-notifications-backend': patch +--- + +Show default settings for notifications even before receiving first notification. + +Previously, it was not possible for the users to see or modify their notification settings until they had received at +least one notification from specific origin or topic. +This update ensures that default settings are displayed from the outset, +allowing users to customize their preferences immediately. diff --git a/.changeset/fix-text-truncate-prop.md b/.changeset/fix-text-truncate-prop.md new file mode 100644 index 0000000000..26aee3280c --- /dev/null +++ b/.changeset/fix-text-truncate-prop.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed Text component to prevent `truncate` prop from being spread to the underlying DOM element. diff --git a/.changeset/flat-paws-do.md b/.changeset/flat-paws-do.md new file mode 100644 index 0000000000..13d78c1423 --- /dev/null +++ b/.changeset/flat-paws-do.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-openapi': patch +--- + +fix wrong dereferencing for AsyncApi 3 documents diff --git a/.changeset/fruity-snails-laugh.md b/.changeset/fruity-snails-laugh.md new file mode 100644 index 0000000000..3b7775efac --- /dev/null +++ b/.changeset/fruity-snails-laugh.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': minor +--- + +fix scaffolder action createDeployToken to allow usage of oauth tokens diff --git a/.changeset/funny-stars-open.md b/.changeset/funny-stars-open.md new file mode 100644 index 0000000000..336e68bac1 --- /dev/null +++ b/.changeset/funny-stars-open.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fix inconsistent behavior in the `new` command for the `@internal` scope: it now consistently defaults to the `backstage-plugin-` infix whether the `--scope` option is not set or it's set to `internal`. diff --git a/.changeset/gentle-bikes-relax.md b/.changeset/gentle-bikes-relax.md new file mode 100644 index 0000000000..7a4aeda5f8 --- /dev/null +++ b/.changeset/gentle-bikes-relax.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-module-addons-contrib': patch +--- + +ExpandableCollapse Techdocs Addon was breaking native sidebar collapse on Firefox diff --git a/.changeset/giant-lamps-happen.md b/.changeset/giant-lamps-happen.md new file mode 100644 index 0000000000..1bc4ae6eab --- /dev/null +++ b/.changeset/giant-lamps-happen.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Improved the Link component structure in Backstage UI. diff --git a/.changeset/heavy-cars-wash.md b/.changeset/heavy-cars-wash.md new file mode 100644 index 0000000000..87da5a6d95 --- /dev/null +++ b/.changeset/heavy-cars-wash.md @@ -0,0 +1,70 @@ +--- +'@backstage/plugin-catalog-backend-module-ldap': minor +--- + +Moved from `ldapjs` dependency to `ldapts` + +### Breaking Changes + +**Type Migration** + +Custom transformers must now accept `Entry` from ldapts instead of `SearchEntry` +from ldapjs The Entry type provides direct property access without need for +`.object()` or `.raw()` methods. + +If you have custom user or group transformers, update the signature from: + +```typescript +(vendor: LdapVendor, config: UserConfig, entry: SearchEntry) => + Promise; +``` + +to + +```typescript +(vendor: LdapVendor, config: UserConfig, entry: Entry) => + Promise; +``` + +**Search Options** + +Updated LDAP search configuration `typesOnly: false` → `attributeValues: true` +This inverts the boolean logic: ldapjs used negative form while ldapts uses +positive form. Both achieve the same result: retrieving attribute values rather +than just attribute names. + +Update LDAP search options in configuration from + +```yaml +options: + typesOnly: false +``` + +to + +```yaml +options: + attributeValues: true +``` + +**API Changes** Removed `LdapClient.searchStreaming()` method. Users should +migrate to `LdapClient.search()` instead + +If you're using `searchStreaming` directly: + +```typescript +// Before +await client.searchStreaming(dn, options, async entry => { + // process each entry +}); + +// After +const entries = await client.search(dn, options); +for (const entry of entries) { + // process each entry +} +``` + +> **_NOTE:_**: Both methods have always loaded all entries into memory. The +> searchStreaming method was only needed internally to handle ldapjs's +> event-based API. diff --git a/.changeset/honest-lamps-occur.md b/.changeset/honest-lamps-occur.md new file mode 100644 index 0000000000..27b2eb44f5 --- /dev/null +++ b/.changeset/honest-lamps-occur.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed dialog backdrop appearance in dark mode. diff --git a/.changeset/honest-pandas-win.md b/.changeset/honest-pandas-win.md new file mode 100644 index 0000000000..a9dc5d7e9d --- /dev/null +++ b/.changeset/honest-pandas-win.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': minor +--- + +Promote `instanceMetadata` service to main entrypoint. diff --git a/.changeset/huge-taxis-grab.md b/.changeset/huge-taxis-grab.md new file mode 100644 index 0000000000..a021fcb82c --- /dev/null +++ b/.changeset/huge-taxis-grab.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Migrated CellProfile component from Base UI Avatar to Backstage UI Avatar component. diff --git a/.changeset/itchy-bars-smell.md b/.changeset/itchy-bars-smell.md new file mode 100644 index 0000000000..b82779502e --- /dev/null +++ b/.changeset/itchy-bars-smell.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': minor +--- + +Fixing styles on SearchField in Backstage UI after migration to CSS modules. `SearchField` has now its own set of class names. We previously used class names from `TextField` but this approach was creating some confusion so going forward in your theme you'll be able to theme `TextField` and `SearchField` separately. diff --git a/.changeset/legal-weeks-walk.md b/.changeset/legal-weeks-walk.md new file mode 100644 index 0000000000..2068ff40b2 --- /dev/null +++ b/.changeset/legal-weeks-walk.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Added `@backstage/plugin-app-visualizer` to the app in the `--next` template. diff --git a/.changeset/lemon-spies-sleep.md b/.changeset/lemon-spies-sleep.md new file mode 100644 index 0000000000..15ec451f62 --- /dev/null +++ b/.changeset/lemon-spies-sleep.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Apply default ordering of templates diff --git a/.changeset/long-humans-sink.md b/.changeset/long-humans-sink.md new file mode 100644 index 0000000000..9959caf1b1 --- /dev/null +++ b/.changeset/long-humans-sink.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Avatar components in x-small and small sizes now display only one initial instead of two, improving readability at smaller dimensions. diff --git a/.changeset/long-impalas-burn.md b/.changeset/long-impalas-burn.md new file mode 100644 index 0000000000..ef70f65f78 --- /dev/null +++ b/.changeset/long-impalas-burn.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': minor +--- + +The `package-docs` command will now automatically use a `typedoc.json` file if one exists at the root of your project. diff --git a/.changeset/moody-plums-add.md b/.changeset/moody-plums-add.md new file mode 100644 index 0000000000..a88e11b347 --- /dev/null +++ b/.changeset/moody-plums-add.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-gateway-backend': minor +--- + +Update usage of the `instanceMetadata` service. diff --git a/.changeset/odd-states-melt.md b/.changeset/odd-states-melt.md new file mode 100644 index 0000000000..514e890bab --- /dev/null +++ b/.changeset/odd-states-melt.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': minor +--- + +Explicitly mark `coreServices.rootInstanceMetadata` as a root service. diff --git a/.changeset/open-cloths-listen.md b/.changeset/open-cloths-listen.md new file mode 100644 index 0000000000..3af368c7ce --- /dev/null +++ b/.changeset/open-cloths-listen.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Tweak some of the mock services to have more precise types diff --git a/.changeset/open-items-open.md b/.changeset/open-items-open.md new file mode 100644 index 0000000000..12fcefab4a --- /dev/null +++ b/.changeset/open-items-open.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': minor +--- + +Updates API for `instanceMetadata` service to return a list of plugins not features. diff --git a/.changeset/plugin-relative-extensions.md b/.changeset/plugin-relative-extensions.md new file mode 100644 index 0000000000..dc27a2283f --- /dev/null +++ b/.changeset/plugin-relative-extensions.md @@ -0,0 +1,17 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Added support for plugin-relative `attachTo` declarations for extension definitions. This allows for the creation of extension and extension blueprints that attach to other extensions of a particular `kind` in the same plugin, rather than needing to provide the exact extension ID. This is particularly useful when wanting to provide extension blueprints with a built-in hierarchy where the extensions created from one blueprint attach to extensions created from the other blueprint, for example: + +```ts +// kind: 'tabbed-page' +const parentPage = TabbedPageBlueprint.make({ + params: {....} +}) +// attachTo: { kind: 'tabbed-page', input: 'tabs' } +const child1 = TabContentBlueprint.make({ + name: 'tab1', + params: {....} +}) +``` diff --git a/.changeset/polite-eggs-dance.md b/.changeset/polite-eggs-dance.md new file mode 100644 index 0000000000..e9725be567 --- /dev/null +++ b/.changeset/polite-eggs-dance.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Removed `@base-ui-components/react` dependency as all components now use React Aria Components. diff --git a/.changeset/pre.json b/.changeset/pre.json index 67e48bb29c..f068415e9f 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -207,25 +207,87 @@ "@backstage/plugin-user-settings-common": "0.0.1" }, "changesets": [ + "all-camels-agree", + "all-parrots-change", "better-hats-cross", "better-steaks-act", + "breezy-times-ring", + "bright-ears-send", + "busy-goats-create", + "clever-boats-clap", + "create-app-1761312116", + "create-app-1762897504", + "cruel-items-dig", + "cruel-plums-talk", + "deep-gifts-slide", + "easy-hands-grow", + "eighty-mails-leave", + "eighty-results-prove", + "eleven-carpets-win", + "eleven-lights-taste", "every-ants-count", "every-clocks-arrive", + "fancy-years-camp", + "fast-tables-sink", + "fast-tools-mate", "fine-hands-return", "five-seas-jam", + "fix-text-truncate-prop", + "flat-paws-do", + "fruity-snails-laugh", + "funny-stars-open", + "gentle-bikes-relax", + "giant-lamps-happen", "grumpy-planes-bet", + "heavy-cars-wash", + "honest-lamps-occur", + "honest-pandas-win", + "huge-taxis-grab", + "itchy-bars-smell", + "legal-weeks-walk", + "lemon-spies-sleep", + "long-humans-sink", + "long-impalas-burn", "loud-carpets-throw", + "moody-plums-add", "ninety-cobras-feel", + "odd-states-melt", + "open-cloths-listen", + "open-items-open", + "plugin-relative-extensions", + "polite-eggs-dance", "polite-seas-divide", + "pretty-kids-allow", + "purple-deer-bet", + "quiet-singers-pick", + "renovate-cd75086", "rich-streets-rule", + "ripe-crabs-care", + "seven-cycles-pick", + "sharp-dragons-relate", "short-sides-feel", "silver-garlics-thank", + "sixty-clowns-run", + "smart-donuts-teach", "solid-bees-agree", "solid-dancers-march", "stupid-doodles-love", + "ten-houses-attack", "tender-regions-know", + "thirty-hoops-own", + "tough-sloths-spend", + "true-taxes-cover", + "twelve-spoons-feel", "typescript-constructor-refactor", + "upset-teeth-add", + "warm-carrots-lead", + "warm-ducks-notice", "warm-moments-repeat", - "wild-owls-divide" + "warm-shrimps-clap", + "wicked-cycles-enter", + "wide-papers-run", + "wild-donkeys-sneeze", + "wild-owls-divide", + "yummy-socks-brake" ] } diff --git a/.changeset/pretty-kids-allow.md b/.changeset/pretty-kids-allow.md new file mode 100644 index 0000000000..6b3b11a895 --- /dev/null +++ b/.changeset/pretty-kids-allow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-github': patch +--- + +Added configurable `pageSizes` for GitHub GraphQL API queries to prevent `RESOURCE_LIMITS_EXCEEDED` errors with organizations with large number of repositories. Please see the [GitHub Discovery documentation](https://backstage.io/docs/integrations/github/discovery#configuration) for new configuration options. diff --git a/.changeset/purple-deer-bet.md b/.changeset/purple-deer-bet.md new file mode 100644 index 0000000000..c60f2ada7a --- /dev/null +++ b/.changeset/purple-deer-bet.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +Ensure the catalog graph entity card respects the height prop so the visualization scales down properly on wide screens. diff --git a/.changeset/quiet-singers-pick.md b/.changeset/quiet-singers-pick.md new file mode 100644 index 0000000000..cc66db1bcd --- /dev/null +++ b/.changeset/quiet-singers-pick.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-signals': patch +--- + +Fixes a bug where the `SignalClient` would try to subscribe to the same channel twice after an error, instead of just once. diff --git a/.changeset/renovate-cd75086.md b/.changeset/renovate-cd75086.md new file mode 100644 index 0000000000..5bc38af431 --- /dev/null +++ b/.changeset/renovate-cd75086.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-common': patch +'@backstage/plugin-kubernetes-node': patch +'@backstage/plugin-kubernetes-react': patch +--- + +Updated dependency `@kubernetes/client-node` to `1.4.0`. diff --git a/.changeset/ripe-crabs-care.md b/.changeset/ripe-crabs-care.md new file mode 100644 index 0000000000..d8cdc27652 --- /dev/null +++ b/.changeset/ripe-crabs-care.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed RadioGroup radio button ellipse distortion by preventing flex shrink and grow. diff --git a/.changeset/seven-cycles-pick.md b/.changeset/seven-cycles-pick.md new file mode 100644 index 0000000000..fbd1a3895f --- /dev/null +++ b/.changeset/seven-cycles-pick.md @@ -0,0 +1,17 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: Changed className prop behavior to augment default styles instead of being ignored or overriding them. + +Affected components: + +- Menu, MenuListBox, MenuAutocomplete, MenuAutocompleteListbox, MenuItem, MenuListBoxItem, MenuSection, MenuSeparator +- Switch +- Skeleton +- FieldLabel +- Header, HeaderToolbar +- HeaderPage +- Tabs, TabList, Tab, TabPanel + +If you were passing custom className values to any of these components that relied on the previous behavior, you may need to adjust your styles to account for the default classes now being applied alongside your custom classes. diff --git a/.changeset/sharp-dragons-relate.md b/.changeset/sharp-dragons-relate.md new file mode 100644 index 0000000000..1f7e5e0d4a --- /dev/null +++ b/.changeset/sharp-dragons-relate.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-app-visualizer': patch +--- + +Migrated to use `@backstage/ui`. diff --git a/.changeset/sixty-clowns-run.md b/.changeset/sixty-clowns-run.md new file mode 100644 index 0000000000..595049df8f --- /dev/null +++ b/.changeset/sixty-clowns-run.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Line numbers in LogViewer will not be selectable in UI anymore diff --git a/.changeset/smart-donuts-teach.md b/.changeset/smart-donuts-teach.md new file mode 100644 index 0000000000..f258dee394 --- /dev/null +++ b/.changeset/smart-donuts-teach.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Enable tree-shaking of imports other than `*.css`. diff --git a/.changeset/ten-houses-attack.md b/.changeset/ten-houses-attack.md new file mode 100644 index 0000000000..9bb1ad2565 --- /dev/null +++ b/.changeset/ten-houses-attack.md @@ -0,0 +1,15 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +'@backstage/plugin-scaffolder-backend-module-rails': patch +'@backstage/plugin-permission-backend': patch +'@backstage/plugin-permission-common': patch +'@backstage/core-components': patch +'@backstage/core-plugin-api': patch +'@backstage/plugin-devtools-common': patch +'@backstage/plugin-search-backend': patch +'@backstage/core-app-api': patch +'@backstage/plugin-catalog-graph': patch +'@backstage/cli': patch +--- + +Convert all enums to erasable-syntax compliant patterns diff --git a/.changeset/thirty-hoops-own.md b/.changeset/thirty-hoops-own.md new file mode 100644 index 0000000000..88b55d5f98 --- /dev/null +++ b/.changeset/thirty-hoops-own.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Updated to `ExtensionInput` to make all type parameters optional. diff --git a/.changeset/tough-sloths-spend.md b/.changeset/tough-sloths-spend.md new file mode 100644 index 0000000000..ed6a4ab366 --- /dev/null +++ b/.changeset/tough-sloths-spend.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-github-org': patch +--- + +Added configurable `pageSizes` for GitHub GraphQL API queries to prevent `RESOURCE_LIMITS_EXCEEDED` errors with organizations with large number of teams and members. Please see the [GitHub Org Data documentation](https://backstage.io/docs/integrations/github/org#configuration-details) for new configuration options. diff --git a/.changeset/true-taxes-cover.md b/.changeset/true-taxes-cover.md new file mode 100644 index 0000000000..ec204084d0 --- /dev/null +++ b/.changeset/true-taxes-cover.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Added `loading` prop to Button and ButtonIcon components for displaying spinner during async operations. diff --git a/.changeset/twelve-spoons-feel.md b/.changeset/twelve-spoons-feel.md new file mode 100644 index 0000000000..21298b4e09 --- /dev/null +++ b/.changeset/twelve-spoons-feel.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend': minor +'@backstage/plugin-catalog-node': minor +--- + +Enable YAML merge keys in yamlPlaceholderResolver diff --git a/.changeset/upset-teeth-add.md b/.changeset/upset-teeth-add.md new file mode 100644 index 0000000000..834ce7be2c --- /dev/null +++ b/.changeset/upset-teeth-add.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-mui-to-bui': patch +--- + +Updated BUI checkbox preview example to align with new component API. diff --git a/.changeset/warm-carrots-lead.md b/.changeset/warm-carrots-lead.md new file mode 100644 index 0000000000..fdc84d026a --- /dev/null +++ b/.changeset/warm-carrots-lead.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed Table Row component to properly support opening links in new tabs via right-click or Cmd+Click when using the href prop. diff --git a/.changeset/warm-ducks-notice.md b/.changeset/warm-ducks-notice.md new file mode 100644 index 0000000000..95e28b0836 --- /dev/null +++ b/.changeset/warm-ducks-notice.md @@ -0,0 +1,39 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: Removed `Collapsible` component. Migrate to `Accordion` or use React Aria `Disclosure`. + +## Migration Path 1: Accordion (Opinionated Styled Component) + +Accordion provides preset styling with a similar component structure. + +```diff +- import { Collapsible } from '@backstage/ui'; ++ import { Accordion, AccordionTrigger, AccordionPanel } from '@backstage/ui'; + +- +- } /> +- Content +- + ++ ++ ++ Content ++ +``` + +CSS classes: `.bui-CollapsibleRoot` → `.bui-Accordion`, `.bui-CollapsibleTrigger` → `.bui-AccordionTrigger` (now on heading element), `.bui-CollapsiblePanel` → `.bui-AccordionPanel` + +## Migration Path 2: React Aria Disclosure (Full Customization) + +For custom styling without preset styles: + +```tsx +import { Disclosure, Button, DisclosurePanel } from 'react-aria-components'; + + + + Content +; +``` diff --git a/.changeset/warm-shrimps-clap.md b/.changeset/warm-shrimps-clap.md new file mode 100644 index 0000000000..0386df05de --- /dev/null +++ b/.changeset/warm-shrimps-clap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch +--- + +Correctly handle entity removal computation when DB count query returns string diff --git a/.changeset/wicked-cycles-enter.md b/.changeset/wicked-cycles-enter.md new file mode 100644 index 0000000000..cea5cff371 --- /dev/null +++ b/.changeset/wicked-cycles-enter.md @@ -0,0 +1,9 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: The `SelectProps` interface now accepts a generic type parameter for selection mode. + +Added searchable and multiple selection support to Select component. The component now accepts `searchable`, `selectionMode`, and `searchPlaceholder` props to enable filtering and multi-selection modes. + +Migration: If you're using `SelectProps` type directly, update from `SelectProps` to `SelectProps<'single' | 'multiple'>`. Component usage remains backward compatible. diff --git a/.changeset/wide-papers-run.md b/.changeset/wide-papers-run.md new file mode 100644 index 0000000000..e0e16d71af --- /dev/null +++ b/.changeset/wide-papers-run.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Set the color-scheme property depending on theme diff --git a/.changeset/wild-donkeys-sneeze.md b/.changeset/wild-donkeys-sneeze.md new file mode 100644 index 0000000000..5e2c4474c5 --- /dev/null +++ b/.changeset/wild-donkeys-sneeze.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Added new VisuallyHidden component for hiding content visually while keeping it accessible to screen readers. diff --git a/.changeset/yummy-socks-brake.md b/.changeset/yummy-socks-brake.md new file mode 100644 index 0000000000..4f3dcfb598 --- /dev/null +++ b/.changeset/yummy-socks-brake.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Allow configuring dynamic client registration token expiration with config `auth.experimentalDynamicClientRegistration.tokenExpiration`. + +Maximum expiration for the DCR token is 24 hours. Default expiration is 1 hour. diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index f4091717b5..80d55d498a 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -110,6 +110,7 @@ dependabot deps dequeue dequeueing +dereferencing deserialization destructured destructuring @@ -179,6 +180,7 @@ graphql GraphQL graphviz Hackathons +hackathon haproxy hardcoded hardcoding @@ -228,6 +230,7 @@ JWTs Kaewkasi Kaswell keepalive +Keycloak Keyv Knex knip @@ -568,3 +571,4 @@ Zolotusky zoomable zsh resizable +enums diff --git a/.github/workflows/api-breaking-changes-comment.yml b/.github/workflows/api-breaking-changes-comment.yml index f419a12599..981d5cb4d6 100644 --- a/.github/workflows/api-breaking-changes-comment.yml +++ b/.github/workflows/api-breaking-changes-comment.yml @@ -99,11 +99,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - name: Fetch cached Manifests File id: cache - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: comment.md key: ${{ needs.setup.outputs.comment-cache-key }} diff --git a/.github/workflows/ci-noop.yml b/.github/workflows/ci-noop.yml index 35901d37b2..0fce9ad6b9 100644 --- a/.github/workflows/ci-noop.yml +++ b/.github/workflows/ci-noop.yml @@ -24,7 +24,7 @@ jobs: name: Verify ${{ matrix.node-version }} steps: # - name: Harden Runner - # uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 + # uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.5.1 # with: # egress-policy: audit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24f08544aa..8aabe7de58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -236,7 +236,7 @@ jobs: # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds - name: restore backstage-cli cache - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .cache/backstage-cli key: ${{ runner.os }}-v${{ matrix.node-version }}-backstage-cli-${{ github.run_id }} @@ -260,7 +260,7 @@ jobs: # Always save success cache even if there were failures, that way it can be used in re-triggered builds - name: save backstage-cli cache - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 if: always() with: path: .cache/backstage-cli diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index ff0b46f0df..2d61bcc19b 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -28,7 +28,7 @@ jobs: egress-policy: audit - name: find latest release - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 id: find-release with: script: | @@ -82,7 +82,7 @@ jobs: # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds - name: restore package-docs cache - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .cache/package-docs key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-stable-${{ github.run_id }} @@ -102,7 +102,7 @@ jobs: # Always save success cache even if there were failures, that way it can be used in re-triggered builds - name: save package-docs cache - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 if: always() with: path: .cache/package-docs @@ -166,7 +166,7 @@ jobs: # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds - name: restore package-docs cache - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .cache/package-docs key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-${{ github.run_id }} @@ -186,7 +186,7 @@ jobs: # Always save success cache even if there were failures, that way it can be used in re-triggered builds - name: save package-docs cache - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 if: always() with: path: .cache/package-docs @@ -329,7 +329,7 @@ jobs: run: ls microsite/build && ls microsite/build/storybook && ls microsite/build/api/stable && ls microsite/build/api/next - name: Deploy both microsite and storybook to gh-pages - uses: JamesIves/github-pages-deploy-action@6c2d9db40f9296374acc17b90404b6e8864128c8 # v4.7.3 + uses: JamesIves/github-pages-deploy-action@4a3abc783e1a24aeb44c16e869ad83caf6b4cc23 # v4.7.4 with: branch: gh-pages folder: microsite/build diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index e3e109dfe7..9e4e504e60 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -94,7 +94,7 @@ jobs: run: yarn backstage-cli config:check --lax - name: backstage-cli cache - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .cache/backstage-cli key: ${{ runner.os }}-v${{ matrix.node-version }}-backstage-cli-${{ github.run_id }} diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml index 17c76c19c2..a759adcb46 100644 --- a/.github/workflows/issue.yaml +++ b/.github/workflows/issue.yaml @@ -22,7 +22,7 @@ jobs: # We need to checkout the `.github/ISSUE_TEMPLATE` for the advanced labeler action to be able to read the templates # While at it we might as well checkout all of `.github` so that the labeling actions don't need to fetch their configs - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: sparse-checkout: .github diff --git a/.github/workflows/mui-migration-tracker.yml b/.github/workflows/mui-migration-tracker.yml new file mode 100644 index 0000000000..4754ec51b0 --- /dev/null +++ b/.github/workflows/mui-migration-tracker.yml @@ -0,0 +1,70 @@ +name: MUI to BUI Migration Tracker + +on: + schedule: + # Run daily at midnight UTC + - cron: '0 0 * * *' + workflow_dispatch: + # Allow manual triggering + +permissions: + issues: write + contents: read + +jobs: + update-migration-progress: + runs-on: ubuntu-latest + name: Update Migration Progress Issue + + steps: + - name: Harden Runner + uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 20.x + registry-url: https://registry.npmjs.org/ # Needed for auth + + - name: yarn install + uses: backstage/actions/yarn-install@b3c1841fd69e1658ac631afafd0fb140a2309024 # v0.6.17 + with: + cache-prefix: ${{ runner.os }}-v20.x + + - name: Run migration analysis + id: analysis + run: | + # Run the migration script and save markdown output + yarn mui-to-bui --markdown > migration-report.md + + # Read the report into an environment variable (escape for GitHub Actions) + echo "REPORT<> $GITHUB_ENV + cat migration-report.md >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Update GitHub Issue + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const issueNumber = 31467; + const reportBody = process.env.REPORT; + + try { + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + body: reportBody + }); + + console.log(`✅ Successfully updated issue #${issueNumber}`); + } catch (error) { + console.error(`❌ Error updating issue: ${error.message}`); + throw error; + } diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 232d055072..0766d1c8a5 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -39,7 +39,7 @@ jobs: persist-credentials: false - name: 'Run analysis' - uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index 3716c1f48b..f18455f5fc 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -29,7 +29,7 @@ jobs: cache-prefix: ${{ runner.os }}-v20.x - name: Create Snyk report - uses: snyk/actions/node@77490d94e966421e076e95ad8fa87aa55e5ca409 # master + uses: snyk/actions/node@9adf32b1121593767fc3c057af55b55db032dc04 # master continue-on-error: true # Snyk CLI exits with error when vulnerabilities are found with: args: > diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index 205d146bb8..b928586aa8 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Monitor and Synchronize Snyk Policies - uses: snyk/actions/node@77490d94e966421e076e95ad8fa87aa55e5ca409 # master + uses: snyk/actions/node@9adf32b1121593767fc3c057af55b55db032dc04 # master with: command: monitor args: > @@ -46,7 +46,7 @@ jobs: # Above we run the `monitor` command, this runs the `test` command which is # the one that generates the SARIF report that we can upload to GitHub. - name: Create Snyk report - uses: snyk/actions/node@77490d94e966421e076e95ad8fa87aa55e5ca409 # master + uses: snyk/actions/node@9adf32b1121593767fc3c057af55b55db032dc04 # master continue-on-error: true # To make sure that SARIF upload gets called with: args: > diff --git a/.github/workflows/verify_chromatic.yml b/.github/workflows/verify_chromatic.yml index 0c9f110b4c..e6649c3e55 100644 --- a/.github/workflows/verify_chromatic.yml +++ b/.github/workflows/verify_chromatic.yml @@ -64,21 +64,29 @@ jobs: - name: Prepare Chromatic Message if: github.event_name == 'pull_request' && steps.chromatic.outputs.url - id: prepare-message + id: prepareMessage run: | if [ "${{ steps.chromatic.outputs.changeCount }}" = "0" ] || [ -z "${{ steps.chromatic.outputs.changeCount }}" ]; then - echo "changes-text=No visual changes detected - [**View build in Chromatic**](${{ steps.chromatic.outputs.buildUrl }})" >> $GITHUB_OUTPUT + echo "changesText=No visual changes detected - [**View build in Chromatic**](${{ steps.chromatic.outputs.buildUrl }})" >> $GITHUB_OUTPUT else - echo "changes-text=**${{ steps.chromatic.outputs.changeCount }}** visual changes are waiting for review - [**Review changes in Chromatic**](${{ steps.chromatic.outputs.buildUrl }})" >> $GITHUB_OUTPUT + echo "changesText=**${{ steps.chromatic.outputs.changeCount }}** visual changes are waiting for review - [**Review changes in Chromatic**](${{ steps.chromatic.outputs.buildUrl }})" >> $GITHUB_OUTPUT fi - - name: Post Chromatic Link in PR Comment + - name: Post Chromatic Results to Job Summary if: github.event_name == 'pull_request' && steps.chromatic.outputs.url + run: | + echo "## 🎨 Visual Testing with Chromatic" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- ${{ steps.prepareMessage.outputs.changesText }}" >> $GITHUB_STEP_SUMMARY + echo "- **${{ steps.chromatic.outputs.specCount}}** stories for **${{ steps.chromatic.outputs.componentCount}}** Components - [**Preview changes in Storybook**](${{ steps.chromatic.outputs.storybookUrl }})" >> $GITHUB_STEP_SUMMARY + + - name: Post Chromatic Link in PR Comment + if: github.event_name == 'pull_request' && steps.chromatic.outputs.url && github.event.pull_request.head.repo.full_name == github.repository uses: mshick/add-pr-comment@v2 with: message: | ## 🎨 Visual Testing with Chromatic - - ${{ steps.prepare-message.outputs.changes-text }} + - ${{ steps.prepareMessage.outputs.changesText }} - **${{ steps.chromatic.outputs.specCount}}** stories for **${{ steps.chromatic.outputs.componentCount}}** Components - [**Preview changes in Storybook**](${{ steps.chromatic.outputs.storybookUrl }}) repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index f3d48ef480..67ac397d43 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -33,7 +33,7 @@ jobs: egress-policy: audit - name: find latest release - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 id: find-release with: script: | @@ -87,7 +87,7 @@ jobs: # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds - name: restore package-docs cache - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .cache/package-docs key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-stable-${{ github.run_id }} @@ -105,7 +105,7 @@ jobs: # Always save success cache even if there were failures, that way it can be used in re-triggered builds - name: save package-docs cache - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 if: always() with: path: .cache/package-docs @@ -168,7 +168,7 @@ jobs: # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds - name: restore package-docs cache - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .cache/package-docs key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-next-${{ github.run_id }} @@ -186,7 +186,7 @@ jobs: # Always save success cache even if there were failures, that way it can be used in re-triggered builds - name: save package-docs cache - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 if: always() with: path: .cache/package-docs diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml new file mode 100644 index 0000000000..5d47ba77da --- /dev/null +++ b/.github/workflows/welcome.yml @@ -0,0 +1,42 @@ +name: Add a welcome comment + +on: + pull_request_target: + types: [opened] + +permissions: + issues: write + pull-requests: write + contents: read + +jobs: + welcome: + runs-on: ubuntu-latest + if: github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + steps: + - name: Add a welcome comment + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const pr = context.payload.pull_request + const login = pr.user.login + + const message = ` + Hi @${login}, thanks for opening your first pull request in Backstage! 👋 + + A couple of useful links to help you get started: + + * [Contributing Guide](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) + * [DCO Sign-off Instructions](https://github.com/backstage/backstage/blob/master/DCO) + * [Style Guide](https://github.com/backstage/backstage/blob/master/STYLE.md) + + We really appreciate your contribution and look forward to reviewing your work. Welcome aboard! + ` + + await github.rest.issues.createComment({ + issue_number: pr.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: message + }) diff --git a/README.md b/README.md index ba44ca951d..545874adf9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ > [!NOTE] -> 🏖 From Monday October 27th through November 3rd, maintainers and Spotify employees will be on vacation due to Wellness Week. Expect the project to move a little slower than normal, and support to be limited. Normal service will resume after that! 🏝 +> ✈️ From Monday November 10th through November 14rd, several maintainers and Spotify employees will be at KubeCon / BackstageCon! Expect the project to move a little slower than normal, and support to be limited. Normal service will resume after that! And do come visit our booth if you are there. ✈️ [![headline](docs/assets/headline.png)](https://backstage.io/) diff --git a/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild b/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild index 47fd506a34..6c87681391 100644 --- a/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild +++ b/contrib/docker/frontend-with-nginx/Dockerfile.dockerbuild @@ -6,7 +6,7 @@ # This dockerfile also performs the build first inside docker. This may come # with a build time impact, but is sometimes desirable. If you want to run the -# build on the host instead, use the file simply named Dockerfile in this folder +# build on the host instead, use the file simply named Dockerfile.hostbuild in this folder # instead. # USAGE: diff --git a/docker-compose.deps.yml b/docker-compose.deps.yml index c7515eca04..2ad65d6085 100644 --- a/docker-compose.deps.yml +++ b/docker-compose.deps.yml @@ -24,7 +24,7 @@ services: timeout: 3s retries: 5 opensearch: - image: opensearchproject/opensearch:2.19.3 + image: opensearchproject/opensearch:2.19.4 environment: plugins.security.disabled: true discovery.type: single-node diff --git a/docs-ui/next.config.mjs b/docs-ui/next.config.mjs index 8e6ed8fdc0..2ff341b609 100644 --- a/docs-ui/next.config.mjs +++ b/docs-ui/next.config.mjs @@ -1,4 +1,6 @@ import createMDX from '@next/mdx'; +import path from 'path'; +import { fileURLToPath } from 'url'; const nextConfig = { pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'], @@ -13,6 +15,10 @@ const nextConfig = { // These are type-level conflicts that don't affect runtime behavior ignoreBuildErrors: true, }, + outputFileTracingRoot: path.join( + path.dirname(fileURLToPath(import.meta.url)), + '..', + ), }; const withMDX = createMDX({}); diff --git a/docs-ui/package.json b/docs-ui/package.json index 17c13f64f3..d05fdf81bb 100644 --- a/docs-ui/package.json +++ b/docs-ui/package.json @@ -7,7 +7,7 @@ "build": "next build", "lint": "next lint", "prestart": "yarn sync:css", - "start": "concurrently \"yarn sync:css:watch\" \"next dev\"", + "start": "next dev", "sync:css": "node scripts/sync-css.js", "sync:css:watch": "node scripts/sync-css.js --watch" }, @@ -16,6 +16,7 @@ "@types/react-dom": "19.1.7" }, "dependencies": { + "@base-ui-components/react": "^1.0.0-beta.4", "@codemirror/lang-sass": "^6.0.2", "@codemirror/view": "^6.34.4", "@lezer/highlight": "^1.2.1", @@ -26,6 +27,7 @@ "@storybook/react": "^8.6.12", "@uiw/codemirror-themes": "^4.23.7", "@uiw/react-codemirror": "^4.23.7", + "clsx": "^2.1.1", "html-react-parser": "^5.2.5", "motion": "^12.4.1", "next": "15.4.7", @@ -43,7 +45,6 @@ "@types/react": "19.1.9", "@types/react-dom": "19.1.7", "chokidar": "^3.6.0", - "concurrently": "^8.2.2", "eslint": "^8", "eslint-config-next": "15.3.4", "lightningcss": "^1.28.2", diff --git a/docs-ui/src/app/about/page.mdx b/docs-ui/src/app/about/page.mdx deleted file mode 100644 index 2c87a3d03e..0000000000 --- a/docs-ui/src/app/about/page.mdx +++ /dev/null @@ -1,32 +0,0 @@ -# About Backstage UI - -Backstage UI is a design system created specifically for Backstage, built with React, TypeScript, and vanilla CSS. -This open-source library is hosted in the Backstage monorepo. While it can be used in other projects, Backstage UI -is designed to deliver a consistent, accessible, and extensible experience tailored to Backstage users. - -## Philosophy - -Backstage empowers product teams to build software faster and with greater quality. Its extensibility, -however, required us to rethink how to deliver a consistent and accessible user experience. Our goal is -to enable plugin creators to design plugins that seamlessly integrate with Backstage's look and feel while -still allowing customization to match individual brands. - -Instead of reinventing the wheel, we chose to focus on layout and styling while leveraging existing headless -component libraries for functionality. This approach allows us to dedicate our efforts to creating a cohesive -and flexible theming system. - -## Team - -Backstage UI is designed and maintained primarily by Spotify's Backstage team, leveraging Spotify's expertise in -crafting high-quality design and technology. Drawing from our experience in building reliable and intuitive -user experiences for the music industry, we've created a design system that looks great and works seamlessly. - -## Community - -Backstage UI is an open-source project and we welcome contributions from the community. If you are interested in -contributing to Backstage UI, please read our [contributing guide](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) -and our [code of conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md). - -## License - -Backstage UI is licensed under the Apache 2.0 license. See the [LICENSE](https://github.com/backstage/backstage/blob/master/LICENSE) file for more details. diff --git a/docs-ui/src/app/components/[slug]/page.tsx b/docs-ui/src/app/components/[slug]/page.tsx index d6f98c8f93..1422334471 100644 --- a/docs-ui/src/app/components/[slug]/page.tsx +++ b/docs-ui/src/app/components/[slug]/page.tsx @@ -7,9 +7,7 @@ export default async function Page({ }) { const { slug } = await params; - const { default: Component } = await import( - `@/content/components/${slug}.mdx` - ); + const { default: Component } = await import(`@/content/${slug}.mdx`); return ; } diff --git a/docs-ui/src/app/components/page.mdx b/docs-ui/src/app/components/page.mdx new file mode 100644 index 0000000000..bd18005d19 --- /dev/null +++ b/docs-ui/src/app/components/page.mdx @@ -0,0 +1,173 @@ +import { ComponentCards, ComponentCard } from '@/components/ComponentCards'; +import { LayoutComponents } from '@/components/LayoutComponents'; +import { CodeBlock } from '@/components/CodeBlock'; + +# Components + +## Layout Components + +We built a couple of layout components to help you build responsive elements +that will be consistent with the rest of your Backstage instance. These +components are opinionated and use TypeScript to ensure that the props you +provide are the ones coming from the theme. + + + Hello World + + Project 1 + Project 2 + + +`} +/> + + + +## Components + +### Actions + + + + + + + + +### Content display + + + + + + +### Selection and inputs + + + + + + + + + + + +### Navigation + + + + + + + + +### Images and icons + + + + + + +### Feedback indicators + + + + + + +### Typography + + + + diff --git a/docs-ui/src/app/install/page.mdx b/docs-ui/src/app/install/page.mdx deleted file mode 100644 index cf14691441..0000000000 --- a/docs-ui/src/app/install/page.mdx +++ /dev/null @@ -1,52 +0,0 @@ -import { CodeBlock } from '@/components/CodeBlock'; -import { Banner } from '@/components/Banner'; -import { snippet } from './snippets'; - -# How to install Backstage UI - -## How to import BUI's global styles - -Backstage UI works by importing a global CSS file at the root of your application. This file includes all the default styles for the components. -First, you'll need to install the package using a package manager. For example, if you're using Yarn: - - - -);`} -/> - - - -## How to use BUI components - -As a plugin maintainer, you can use BUI components in your plugin. As mentioned above, you should not import the styles -again in your plugin as this will be handled at the root of your application. To get started, just add the library to -your plugin and import the components you need. - - - - - -## Next steps - -Now that you have the basics down, you can start building your plugin using the new design system. -Please familiarise yourself first with our theming principles. This will help you understand the core concepts of the design system. -If you have any questions, please reach out to us on [Discord](https://discord.gg/MUpMjP2). diff --git a/docs-ui/src/app/layout.module.css b/docs-ui/src/app/layout.module.css index 7399fc2485..df89f02283 100644 --- a/docs-ui/src/app/layout.module.css +++ b/docs-ui/src/app/layout.module.css @@ -1,28 +1,46 @@ .container { position: relative; z-index: 20; - width: calc(100% - 64px); - margin-inline: 0 16px; - margin-left: 32px; - margin-right: 32px; - margin-top: 112px; margin-bottom: 48px; - padding-inline: 40px; - padding-block: 48px; - background-color: var(--panel); - border-radius: 0.5rem; + padding-inline: 24px; +} + +.contentWrapper { + display: flex; + width: 100%; + max-width: 1200px; + margin: 0 auto; + justify-content: center; + flex-direction: column; } .content { - width: 100%; - max-width: 960px; - margin: 0 auto; + display: flex; + gap: 40px; +} + +.contentInner { + flex: 1; + min-width: 0; + overflow-x: hidden; +} + +.toc { + display: none; } @media (min-width: 768px) { .container { - width: calc(100% - 332px - 40px); - margin-left: 332px; + width: calc(100% - 260px); + margin-left: 260px; margin-right: 40px; } } + +@media (min-width: 1280px) { + .toc { + display: block; + width: 240px; + flex-shrink: 0; + } +} diff --git a/docs-ui/src/app/layout.tsx b/docs-ui/src/app/layout.tsx index d197112431..ad056626d8 100644 --- a/docs-ui/src/app/layout.tsx +++ b/docs-ui/src/app/layout.tsx @@ -1,9 +1,10 @@ import type { Metadata } from 'next'; -import { Sidebar } from '../components/Sidebar'; +import { Sidebar } from '@/components/Sidebar/Sidebar'; import { Toolbar } from '@/components/Toolbar'; -import { StickyHeader } from '../components/StickyHeader/StickyHeader'; import { Providers } from './providers'; import { CustomTheme } from '@/components/CustomTheme'; +import { TableOfContents } from '@/components/TableOfContents'; +import { MobileBottomNav } from '@/components/MobileBottomNav'; import styles from './layout.module.css'; import '../css/globals.css'; @@ -51,11 +52,18 @@ export default async function RootLayout({ - -
-
{children}
+
+ +
+
{children}
+ +
+
+
diff --git a/docs-ui/src/app/layout/page.mdx b/docs-ui/src/app/layout/page.mdx deleted file mode 100644 index 3c3b998490..0000000000 --- a/docs-ui/src/app/layout/page.mdx +++ /dev/null @@ -1,42 +0,0 @@ -import { LayoutComponents } from '@/components/LayoutComponents'; -import { CodeBlock } from '@/components/CodeBlock'; - -# Layout - -Backstage UI is made for extensibility. We built this library to make it easy for any -Backstage plugin creator to be able to build their ideas at speed ensuring -consistency across the rest of your ecosystem. Each component is designed to -be editable to match your need but sometimes you want to have more control -over the layout of your page. To help you with that, we created a set of -layout components that you can use to build your own layouts. All of these -components are built to extend on our theming system, making it easy for you -to build your own layouts. Sometimes these components are not enough so we -created a set of helpers to be used with any CSS-in-JS library. - -## Layout Components - -We built a couple of layout components to help you build responsive elements -that will be consistent with the rest of your Backstage instance. These -components are opinionated and use TypeScript to ensure that the props you -provide are the ones coming from the theme. - - - Hello World - - Project 1 - Project 2 - - -`} -/> - - - -## Layout Helpers - -Sometimes you want to use global tokens dynamically outside of React -components. To help you with that we would like to provide a set of helpers -that you can use in your code. These helpers are not available just yet but we -are working on it. diff --git a/docs-ui/src/app/page.mdx b/docs-ui/src/app/page.mdx index ffd3bc9dcb..9a796b401b 100644 --- a/docs-ui/src/app/page.mdx +++ b/docs-ui/src/app/page.mdx @@ -1,179 +1,83 @@ -import { ComponentCards, ComponentCard } from '@/components/ComponentCards'; +import { CodeBlock } from '@/components/CodeBlock'; +import { Banner } from '@/components/Banner'; +import { snippet } from './snippets'; -## Welcome to Backstage UI, the new design library for Backstage plugins. +# Welcome to Backstage UI -This project is still under active development but we will make sure to document -the API as we go. We are aiming to improve the general UI of Backstage and -plugins across Backstage. This new library will take time to build but we are -building it incrementally with not conflict with the existing theming system. +Backstage UI is a design system created specifically for Backstage, built with React, TypeScript, and vanilla CSS. +This open-source library is hosted in the Backstage monorepo. While it can be used in other projects, Backstage UI +is designed to deliver a consistent, accessible, and extensible experience tailored to Backstage users. -### Actions +## Import BUI's global styles - - - - - - +Backstage UI works by importing a global CSS file at the root of your application. This file includes all the default styles for the components. +First, you'll need to install the package using a package manager. For example, if you're using Yarn: -### Layout + - - - - - - - - +);`} +/> - - - - - - - - - + -### Navigation +## Use BUI components - - - - - - +As a plugin maintainer, you can use BUI components in your plugin. As mentioned above, you should not import the styles +again in your plugin as this will be handled at the root of your application. To get started, just add the library to +your plugin and import the components you need. -### Images and icons + - - - - - -### Feedback indicators - - - - - - -### Typography - - - - + ## Support Now that you have the basics down, you can start building your plugin using the new design system. Please familiarise yourself first with our theming principles. This will help you understand the core concepts of the design system. If you have any questions, please reach out to us on [Discord](https://discord.gg/MUpMjP2). + +## Philosophy + +Backstage empowers product teams to build software faster and with greater quality. Its extensibility, +however, required us to rethink how to deliver a consistent and accessible user experience. Our goal is +to enable plugin creators to design plugins that seamlessly integrate with Backstage's look and feel while +still allowing customization to match individual brands. + +Instead of reinventing the wheel, we chose to focus on layout and styling while leveraging existing headless +component libraries for functionality. This approach allows us to dedicate our efforts to creating a cohesive +and flexible theming system. + +## Team + +Backstage UI is designed and maintained primarily by Spotify's Backstage team, leveraging Spotify's expertise in +crafting high-quality design and technology. Drawing from our experience in building reliable and intuitive +user experiences for the music industry, we've created a design system that looks great and works seamlessly. + +## Community + +Backstage UI is an open-source project and we welcome contributions from the community. If you are interested in +contributing to Backstage UI, please read our [contributing guide](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) +and our [code of conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md). + +## License + +Backstage UI is licensed under the Apache 2.0 license. See the [LICENSE](https://github.com/backstage/backstage/blob/master/LICENSE) file for more details. diff --git a/docs-ui/src/app/responsive/page.mdx b/docs-ui/src/app/responsive/page.mdx deleted file mode 100644 index 9d37b1329f..0000000000 --- a/docs-ui/src/app/responsive/page.mdx +++ /dev/null @@ -1,107 +0,0 @@ -import * as Table from '@/components/Table'; -import { Chip } from '@/components/Chip'; -import { CodeBlock } from '@/components/CodeBlock'; - -# Responsive - -Backstage UI is built on a responsive design system, meaning that the components are -designed to adapt to different screen sizes. By default we offer a set of -breakpoints that you can use to create responsive components. - -## Breakpoints - - - - - Breakpoint prefix - Minimum width - CSS - - - - - - xs - - - 0px - - - {`{ ... }`} - - - - - sm - - - 640px - - - {`@media (min-width: 640px) { ... }`} - - - - - md - - - 768px - - - {`@media (min-width: 768px) { ... }`} - - - - - lg - - - 1024px - - - {`@media (min-width: 1024px) { ... }`} - - - - - xl - - - 1280px - - - {`@media (min-width: 1280px) { ... }`} - - - - - 2xl - - - 1536px - - - {`@media (min-width: 1536px) { ... }`} - - - - - -## Responsive components - -Backstage UI components are designed to be responsive, meaning that they will adapt -to different screen sizes. Not every component is responsive, but the ones -that are will have a prop to control the responsive behavior. - -The behaviour is the same for each component. For each prop, instead of adding -the value, you add an object with the value and the breakpoint prefix. - -Button - -// Responsive value - -`} /> diff --git a/docs-ui/src/app/install/snippets.ts b/docs-ui/src/app/snippets.ts similarity index 100% rename from docs-ui/src/app/install/snippets.ts rename to docs-ui/src/app/snippets.ts diff --git a/docs-ui/src/app/theming/page.mdx b/docs-ui/src/app/tokens/page.mdx similarity index 86% rename from docs-ui/src/app/theming/page.mdx rename to docs-ui/src/app/tokens/page.mdx index 455b2cd7f5..8e9031c81c 100644 --- a/docs-ui/src/app/theming/page.mdx +++ b/docs-ui/src/app/tokens/page.mdx @@ -3,48 +3,109 @@ import * as Table from '@/components/Table'; import { Chip } from '@/components/Chip'; import { customTheme } from '@/snippets/code-snippets'; -# Theming +# Tokens -Backstage UI theming is built entirely on CSS, without relying on any CSS-in-JS libraries. -At its core, it provides a solid default theme that is easily customizable using a -comprehensive set of CSS variables. Additionally, it enables anyone to adapt the design -to their specific needs. Each component comes with fixed class names, making customization -even more straightforward. +## Responsive breakpoints -## Light & Dark modes +Backstage UI is built on a responsive design system, meaning that the components are +designed to adapt to different screen sizes. By default we offer a set of +breakpoints that you can use to create responsive components. -By default, Backstage UI supports both light and dark modes using the `data-theme-mode` attribute. -The light theme is applied by default if no `data-theme-mode` attribute is specified. To create -a custom theme, you'll need to define both light and dark modes as outlined below. If -only one mode is defined, the other will fall back to the default theme. + + + + Breakpoint prefix + Minimum width + CSS + + + + + + xs + + + 0px + + + {`{ ... }`} + + + + + sm + + + 640px + + + {`@media (min-width: 640px) { ... }`} + + + + + md + + + 768px + + + {`@media (min-width: 768px) { ... }`} + + + + + lg + + + 1024px + + + {`@media (min-width: 1024px) { ... }`} + + + + + xl + + + 1280px + + + {`@media (min-width: 1280px) { ... }`} + + + + + 2xl + + + 1536px + + + {`@media (min-width: 1536px) { ... }`} + + + + -## How to create your own theme +Backstage UI components are designed to be responsive, meaning that they will adapt +to different screen sizes. Not every component is responsive, but the ones +that are will have a prop to control the responsive behavior. -In our [started guide](/), we ask you to import two css files. The `core.css` file includes -the default set of variables. We recommend to keep this file in place and add your own theme -on top of it. `core.css` also include an opinionated reset. If you decided to remove `core.css` -you will have to provide your own reset css. +The behaviour is the same for each component. For each prop, instead of adding +the value, you add an object with the value and the breakpoint prefix. -Here's an example of how your theme.css file should look like: + + -## CSS class name structure +// Responsive value -All Backstage UI components come with a set of CSS classes that you can use to style them. To make it -easier to identify the class name you can use, we use a specific structure for the class names. +`} /> - - -Every component has a unique prefix `.bui-` followed by the component name. Component props -are represented using the `data-` attribute. That way, class names are easily identifiable. - -## Available CSS variables - -### Base colors +## Base colors These colors are used for special purposes like ring, scrollbar, ... @@ -123,7 +184,7 @@ These colors are used for special purposes like ring, scrollbar, ... -### Core background colors +## Core background colors These colors are used for the background of your application. We are mostly using for now a single elevated background for panels. `--bui-bg` should mostly use as the main background @@ -224,7 +285,7 @@ color of your app. -### Foreground colors +## Foreground colors Foreground colours are meant to work in pair with a background colours. Typically this would work for icons, texts, shapes, ... Use a matching name to know what foreground color to use. These colors @@ -329,7 +390,7 @@ are prefixed with `fg` to make it easier to identify. -### Border colors +## Border colors These border colors are mostly meant to be used as borders on top of any components with low contrast to help as a separator with the different background colors. @@ -391,7 +452,7 @@ low contrast to help as a separator with the different background colors. -### Special colors +## Special colors These colors are used for special purposes like ring, scrollbar, ... @@ -424,7 +485,7 @@ These colors are used for special purposes like ring, scrollbar, ... -### Font families +## Font families We have two fonts that we use across Backstage UI. The first one is the sans-serif font that we use for the body of the application. The second one is the @@ -453,7 +514,7 @@ monospace font that we use for code blocks and tables. -### Font weights +## Font weights We have two font weights that we use across Backstage UI. Regular or Bold. @@ -480,7 +541,7 @@ We have two font weights that we use across Backstage UI. Regular or Bold. -### Spacing +## Spacing We built a spacing system based on a single value `--bui-space`. This value is used to calculate the spacing for all the components. By default if you would like to @@ -619,7 +680,7 @@ tokens for pretty much each spacing properties like padding, margin, gaps, ... -### Radius +## Radius We use a radius system to make sure that the components have a consistent look and feel. diff --git a/docs-ui/src/components/CodeBlock/index.tsx b/docs-ui/src/components/CodeBlock/index.tsx index 96fdb6bea5..1467bca465 100644 --- a/docs-ui/src/components/CodeBlock/index.tsx +++ b/docs-ui/src/components/CodeBlock/index.tsx @@ -9,15 +9,24 @@ export interface CodeBlockProps { code?: string; } -export async function CodeBlock({ lang = 'tsx', title, code }: CodeBlockProps) { - const out = await codeToHtml(code || '', { - lang: lang, +export async function CodeBlock(props: CodeBlockProps) { + const { lang = 'tsx', title, code } = props; + let out = await codeToHtml(code || '', { + lang, + transformers: [transformerNotationDiff({ matchAlgorithm: 'v3' })], themes: { - light: 'min-light', + light: 'github-dark', dark: 'min-dark', }, - transformers: [transformerNotationDiff({ matchAlgorithm: 'v3' })], }); + // Remove background-color from the pre tag to use our theme colors + out = out.replace( + /style="([^"]*?)background-color:[^;]+;?([^"]*?)"/g, + 'style="$1$2"', + ); + // Clean up empty style attributes + out = out.replace(/style=""\s?/g, ''); + return ; } diff --git a/docs-ui/src/components/CodeBlock/styles.module.css b/docs-ui/src/components/CodeBlock/styles.module.css index d786140482..30e1837f60 100644 --- a/docs-ui/src/components/CodeBlock/styles.module.css +++ b/docs-ui/src/components/CodeBlock/styles.module.css @@ -1,33 +1,29 @@ .codeBlock { - border-radius: 4px; - border: 1px solid var(--border); + border-radius: 8px; position: relative; background: transparent; overflow-x: auto; font-family: var(--font-mono); - background-color: #fff; + background-color: var(--code-bg); margin-bottom: 1rem; } -[data-theme-mode='dark'] .codeBlock { - background-color: #121212; -} - .title { - border-bottom: 1px solid var(--border); padding: 12px 20px; font-size: 0.8125rem; - color: var(--primary); + color: #fff; font-family: var(--font-regular); font-weight: var(--font-weight-bold); + background-color: var(--code-title); } .title code { - background-color: var(--surface-1); + background-color: rgba(255, 255, 255, 0.1); padding: 0.2rem 0.375rem; border-radius: 0.25rem; - color: var(--secondary); - font-size: 0.8125rem; + color: #fff; + font-size: 0.75rem; + font-weight: var(--font-weight-bold); } .code { diff --git a/docs-ui/src/components/ComponentCards/ComponentCards.module.css b/docs-ui/src/components/ComponentCards/ComponentCards.module.css index 688010110c..8eb9dbd3d0 100644 --- a/docs-ui/src/components/ComponentCards/ComponentCards.module.css +++ b/docs-ui/src/components/ComponentCards/ComponentCards.module.css @@ -28,7 +28,7 @@ display: flex; flex-direction: column; justify-content: flex-end; - background-color: var(--panel); + background-color: var(--bg); border-radius: 8px; border: 1px solid var(--border); padding: 16px; @@ -36,7 +36,7 @@ min-height: 120px; &:hover { - background-color: var(--panel-hover); + background-color: var(--bg-hover); } } diff --git a/docs-ui/src/components/CustomTheme/styles.module.css b/docs-ui/src/components/CustomTheme/styles.module.css index 05604c48be..dddd3ff7e4 100644 --- a/docs-ui/src/components/CustomTheme/styles.module.css +++ b/docs-ui/src/components/CustomTheme/styles.module.css @@ -5,7 +5,7 @@ right: 16px; width: 240px; height: 47px; - background-color: var(--panel); + background-color: var(--bg); border-radius: 0.375rem; border: 1px solid var(--border); display: flex; @@ -33,7 +33,7 @@ height: 46px; flex-shrink: 0; border-bottom: 1px solid var(--border); - background-color: var(--panel); + background-color: var(--bg); display: flex; justify-content: space-between; align-items: center; diff --git a/docs-ui/src/components/HeadlessBanners/styles.module.css b/docs-ui/src/components/HeadlessBanners/styles.module.css index 384327c394..c0066eccff 100644 --- a/docs-ui/src/components/HeadlessBanners/styles.module.css +++ b/docs-ui/src/components/HeadlessBanners/styles.module.css @@ -1,6 +1,6 @@ .container { display: flex; - background-color: var(--panel); + background-color: var(--bg); padding: 1.5rem; border-radius: 0.25rem; border: 1px solid var(--border); diff --git a/docs-ui/src/components/LayoutComponents/LayoutComponents.module.css b/docs-ui/src/components/LayoutComponents/LayoutComponents.module.css index a09a04fb5c..9009cdb6a4 100644 --- a/docs-ui/src/components/LayoutComponents/LayoutComponents.module.css +++ b/docs-ui/src/components/LayoutComponents/LayoutComponents.module.css @@ -19,7 +19,7 @@ & .content { flex: none; - background-color: var(--panel); + background-color: var(--bg); border: 1px solid var(--border); border-radius: 4px; width: 100%; diff --git a/docs-ui/src/components/MobileBottomNav/AnimatedMenuIcon.module.css b/docs-ui/src/components/MobileBottomNav/AnimatedMenuIcon.module.css new file mode 100644 index 0000000000..632f005b65 --- /dev/null +++ b/docs-ui/src/components/MobileBottomNav/AnimatedMenuIcon.module.css @@ -0,0 +1,40 @@ +.icon { + display: block; +} + +.topLine, +.middleLine, +.bottomLine { + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +/* Menu state (default) */ +.topLine { + transform-origin: 10px 5px; + transform: rotate(0deg); +} + +.middleLine { + opacity: 1; + transform-origin: 10px 10px; +} + +.bottomLine { + transform-origin: 10px 15px; + transform: rotate(0deg); +} + +/* Close state (when open) */ +.icon[data-open='true'] .topLine { + transform-origin: 10px 5px; + transform: translateY(5px) rotate(45deg); +} + +.icon[data-open='true'] .middleLine { + opacity: 0; +} + +.icon[data-open='true'] .bottomLine { + transform-origin: 10px 15px; + transform: translateY(-5px) rotate(-45deg); +} diff --git a/docs-ui/src/components/MobileBottomNav/AnimatedMenuIcon.tsx b/docs-ui/src/components/MobileBottomNav/AnimatedMenuIcon.tsx new file mode 100644 index 0000000000..80edd64d43 --- /dev/null +++ b/docs-ui/src/components/MobileBottomNav/AnimatedMenuIcon.tsx @@ -0,0 +1,56 @@ +import styles from './AnimatedMenuIcon.module.css'; + +interface AnimatedMenuIconProps { + isOpen: boolean; + size?: number; +} + +export const AnimatedMenuIcon = ({ + isOpen, + size = 20, +}: AnimatedMenuIconProps) => { + return ( + + + + + + + + ); +}; diff --git a/docs-ui/src/components/MobileBottomNav/MobileBottomNav.module.css b/docs-ui/src/components/MobileBottomNav/MobileBottomNav.module.css new file mode 100644 index 0000000000..9c128c3959 --- /dev/null +++ b/docs-ui/src/components/MobileBottomNav/MobileBottomNav.module.css @@ -0,0 +1,205 @@ +/* Mobile Bottom Navigation Island */ +.mobileBottomNav { + display: block; + position: fixed; + bottom: 0; + left: 0; + right: 0; + padding: 16px; + z-index: 300; + pointer-events: none; + + @media (min-width: 768px) { + display: none; + } +} + +.island { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin: 0 auto; + width: 50vw; + padding: 8px 12px 8px 12px; + border-radius: 32px; + pointer-events: auto; + background-color: #000; +} + +:global([data-theme-mode='dark']) .island { + background-color: #fff; + box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3); +} + +.menuButton { + display: flex; + align-items: center; + justify-content: center; + background: none; + border: none; + cursor: pointer; + padding: 8px; + border-radius: 50%; + transition: background-color 0.2s ease-in-out; + + /* White icons on light mode (black island) */ + color: white; + + &:hover { + background-color: rgba(255, 255, 255, 0.1); + } +} + +:global([data-theme-mode='dark']) .menuButton { + /* Black icons on dark mode (white island) */ + color: black; + + &:hover { + background-color: rgba(0, 0, 0, 0.1); + } +} + +.buttonGroup { + display: flex; + align-items: center; + gap: 4px; + padding: 4px; + border-radius: 24px; + background-color: rgba(255, 255, 255, 0.2); +} + +:global([data-theme-mode='dark']) .buttonGroup { + background-color: rgba(0, 0, 0, 0.08); +} + +.buttonGroup button { + display: flex; + align-items: center; + justify-content: center; + background: none; + border: none; + cursor: pointer; + padding: 6px 12px; + border-radius: 20px; + transition: background-color 0.2s ease-in-out; + + /* White icons on light mode */ + color: white; + + &[data-selected] { + background-color: rgba(255, 255, 255, 0.2); + } + + &:hover { + background-color: rgba(255, 255, 255, 0.15); + } +} + +:global([data-theme-mode='dark']) .buttonGroup button { + /* Black icons on dark mode */ + color: black; + + &[data-selected] { + background-color: rgba(0, 0, 0, 0.2); + } + + &:hover { + background-color: rgba(0, 0, 0, 0.15); + } +} + +/* Mobile Menu Bottom Sheet */ +.overlay { + position: fixed; + inset: 0; + z-index: 200; + background-color: rgba(38, 38, 38, 0.7); + display: flex; + align-items: flex-end; + justify-content: center; + + &[data-entering] { + animation: overlayFadeIn 200ms ease-out; + } + + &[data-exiting] { + animation: overlayFadeOut 200ms ease-in; + } +} + +@keyframes overlayFadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes overlayFadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +.modal { + width: calc(100% - 48px); + max-height: 50vh; + background-color: var(--bg); + border-radius: 16px; + box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.2); + display: flex; + flex-direction: column; + outline: none; + margin-bottom: 96px; + + &[data-entering] { + animation: slideUp 300ms cubic-bezier(0.32, 0.72, 0, 1); + } + + &[data-exiting] { + animation: slideDown 200ms cubic-bezier(0.32, 0.72, 0, 1); + } +} + +@keyframes slideUp { + from { + transform: translateY(8%); + } + to { + transform: translateY(0); + } +} + +@keyframes slideDown { + from { + transform: translateY(0); + } + to { + transform: translateY(8%); + } +} + +.dialog { + display: flex; + flex-direction: column; + height: 100%; + max-height: 70vh; + outline: none; + overflow: hidden; +} + +.menuContent { + flex: 1; + overflow-y: auto; + overflow-x: hidden; + padding: 16px; + display: flex; + flex-direction: column; + gap: 2px; + min-height: 0; +} diff --git a/docs-ui/src/components/MobileBottomNav/MobileBottomNav.tsx b/docs-ui/src/components/MobileBottomNav/MobileBottomNav.tsx new file mode 100644 index 0000000000..52ec2ee9d9 --- /dev/null +++ b/docs-ui/src/components/MobileBottomNav/MobileBottomNav.tsx @@ -0,0 +1,44 @@ +'use client'; + +import { useState } from 'react'; +import { RiMoonLine, RiSunLine } from '@remixicon/react'; +import { Button, ToggleButton, ToggleButtonGroup } from 'react-aria-components'; +import styles from './MobileBottomNav.module.css'; +import { usePlayground } from '@/utils/playground-context'; +import { MobileMenu } from './MobileMenu'; +import { AnimatedMenuIcon } from './AnimatedMenuIcon'; + +export const MobileBottomNav = () => { + const [isMenuOpen, setIsMenuOpen] = useState(false); + const { selectedTheme, setSelectedTheme } = usePlayground(); + + return ( + <> +
+
+ + + + + + + + + +
+
+ setIsMenuOpen(false)} /> + + ); +}; diff --git a/docs-ui/src/components/MobileBottomNav/MobileMenu.tsx b/docs-ui/src/components/MobileBottomNav/MobileMenu.tsx new file mode 100644 index 0000000000..3a3a485aa5 --- /dev/null +++ b/docs-ui/src/components/MobileBottomNav/MobileMenu.tsx @@ -0,0 +1,31 @@ +'use client'; + +import { Dialog, Modal, ModalOverlay } from 'react-aria-components'; +import styles from './MobileBottomNav.module.css'; +import { Navigation } from '@/components/Navigation'; + +interface MobileMenuProps { + isOpen: boolean; + onClose: () => void; +} + +export const MobileMenu = ({ isOpen, onClose }: MobileMenuProps) => { + return ( + + + + {({ close }) => ( +
+ +
+ )} +
+
+
+ ); +}; diff --git a/docs-ui/src/components/MobileBottomNav/index.tsx b/docs-ui/src/components/MobileBottomNav/index.tsx new file mode 100644 index 0000000000..4b7449c9c5 --- /dev/null +++ b/docs-ui/src/components/MobileBottomNav/index.tsx @@ -0,0 +1 @@ +export { MobileBottomNav } from './MobileBottomNav'; diff --git a/docs-ui/src/components/Navigation/Navigation.module.css b/docs-ui/src/components/Navigation/Navigation.module.css new file mode 100644 index 0000000000..f5e1312ab1 --- /dev/null +++ b/docs-ui/src/components/Navigation/Navigation.module.css @@ -0,0 +1,100 @@ +.topNav { + & ul { + margin: 0; + padding: 0; + list-style: none; + display: flex; + flex-direction: column; + gap: 2px; + } + + & li { + margin: 0; + padding: 0; + list-style: none; + } + + & li div, + & li a { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + border-radius: 4px; + cursor: pointer; + color: var(--primary); + text-decoration: none; + + &:hover { + background-color: var(--action); + + &[data-disabled='true'] { + background-color: transparent; + } + } + + &[data-active='true'] { + background-color: var(--action); + + &[data-disabled='true'] { + background-color: transparent; + } + } + + &[data-disabled='true'] { + opacity: 0.5; + cursor: not-allowed; + } + } +} + +.sectionTitle { + font-size: 0.6875rem; + font-weight: 500; + padding: 0 12px 4px; + color: var(--secondary); + margin-top: 40px; + text-transform: uppercase; + + &:first-child { + margin-top: 12px; + } +} + +.line { + text-decoration: none; + align-items: center; + width: 100%; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + height: 28px; + padding: 0 12px; + border-radius: 4px; + color: var(--primary); + flex-shrink: 0; + + &:hover { + background-color: var(--action); + } + + &.active { + background-color: var(--action); + } + + &.active .lineTitle { + color: var(--primary); + } +} + +.lineTitle { + font-size: 14px; + font-weight: 400; + color: var(--primary); +} + +.lineStatus { + font-size: 14px; + color: var(--secondary); +} diff --git a/docs-ui/src/components/Navigation/Navigation.tsx b/docs-ui/src/components/Navigation/Navigation.tsx new file mode 100644 index 0000000000..13fa87661f --- /dev/null +++ b/docs-ui/src/components/Navigation/Navigation.tsx @@ -0,0 +1,125 @@ +'use client'; + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import { Fragment } from 'react'; +import clsx from 'clsx'; +import { + RiCollageLine, + RiFileHistoryLine, + RiHazeLine, + RiPaletteLine, + RiServiceLine, + RiStackLine, +} from '@remixicon/react'; +import { components, layoutComponents } from '@/utils/data'; +import styles from './Navigation.module.css'; + +interface NavigationProps { + onLinkClick?: () => void; +} + +const data = [ + { + title: 'Layout Components', + content: layoutComponents, + url: '/components', + }, + { + title: 'Components', + content: components, + url: '/components', + }, +]; + +export const Navigation = ({ onLinkClick }: NavigationProps) => { + const pathname = usePathname(); + + return ( + <> + + {data.map(section => { + return ( + +
{section.title}
+ + {section.content.map(item => { + const isActive = pathname === `${section.url}/${item.slug}`; + + return ( + +
{item.title}
+
+ {item.status === 'alpha' && 'Alpha'} + {item.status === 'beta' && 'Beta'} + {item.status === 'inProgress' && 'In Progress'} + {item.status === 'stable' && 'Stable'} + {item.status === 'deprecated' && 'Deprecated'} +
+ + ); + })} +
+ ); + })} + + ); +}; diff --git a/docs-ui/src/components/Navigation/index.tsx b/docs-ui/src/components/Navigation/index.tsx new file mode 100644 index 0000000000..61f39d15c9 --- /dev/null +++ b/docs-ui/src/components/Navigation/index.tsx @@ -0,0 +1 @@ +export { Navigation } from './Navigation'; diff --git a/docs-ui/src/components/PageTitle/index.tsx b/docs-ui/src/components/PageTitle/index.tsx index 540e19eb36..c43ff75fc7 100644 --- a/docs-ui/src/components/PageTitle/index.tsx +++ b/docs-ui/src/components/PageTitle/index.tsx @@ -5,15 +5,12 @@ import styles from './PageTitle.module.css'; export const PageTitle = ({ title, description, - type = 'component', }: { title: string; - type?: string; description: string; }) => { return (
-
{type}
{ + return ( +
+
+ +
+ + +
+
+ +
+
+
+ + + +
+
+ ); +}; diff --git a/docs-ui/src/components/Sidebar/index.tsx b/docs-ui/src/components/Sidebar/index.tsx deleted file mode 100644 index 59e297e26e..0000000000 --- a/docs-ui/src/components/Sidebar/index.tsx +++ /dev/null @@ -1,104 +0,0 @@ -'use client'; - -import styles from './Sidebar.module.css'; -import { - components, - overview, - layoutComponents, - coreConcepts, -} from '@/utils/data'; -import { ScrollArea } from '@base-ui-components/react/scroll-area'; -import Link from 'next/link'; -import { usePathname } from 'next/navigation'; -import { motion } from 'motion/react'; -import { Fragment } from 'react'; - -const data = [ - { - title: 'Overview', - content: overview, - url: '', - }, - { - title: 'Core Concepts', - content: coreConcepts, - url: '', - }, - { - title: 'Layout Components', - content: layoutComponents, - url: '/components', - }, - { - title: 'Components', - content: components, - url: '/components', - }, -]; - -export const Sidebar = () => { - const pathname = usePathname(); - const isPlayground = pathname.includes('/playground'); - - return ( -
- - -
-
- - {data.map(section => { - return ( - -
{section.title}
- - {section.content.map(item => { - const isActive = - pathname === `${section.url}/${item.slug}`; - - return ( - -
{item.title}
-
- {item.status === 'alpha' && 'Alpha'} - {item.status === 'beta' && 'Beta'} - {item.status === 'inProgress' && 'In Progress'} - {item.status === 'stable' && 'Stable'} - {item.status === 'deprecated' && 'Deprecated'} -
- - ); - })} -
- ); - })} -
-
-
-
- - - -
-
- ); -}; diff --git a/docs-ui/src/components/Snippet/styles.module.css b/docs-ui/src/components/Snippet/styles.module.css index bb0d1cbc50..3141564293 100644 --- a/docs-ui/src/components/Snippet/styles.module.css +++ b/docs-ui/src/components/Snippet/styles.module.css @@ -5,9 +5,9 @@ } .preview { - border-radius: 4px; + border-radius: 8px; box-shadow: inset 0 0 0 1px var(--border); - background-color: var(--bg); + background-color: var(--bui-bg); padding: 1px; position: relative; } diff --git a/docs-ui/src/components/StickyHeader/StickyHeader.module.css b/docs-ui/src/components/StickyHeader/StickyHeader.module.css deleted file mode 100644 index 7cfc197f83..0000000000 --- a/docs-ui/src/components/StickyHeader/StickyHeader.module.css +++ /dev/null @@ -1,98 +0,0 @@ -.stickyHeader { - position: fixed; - top: 0px; - left: 32px; - right: 32px; - z-index: 99999; - background-color: var(--background); - padding: 16px 20px 16px 40px; - display: flex; - justify-content: space-between; - align-items: center; - backdrop-filter: blur(10px); - pointer-events: auto; - isolation: isolate; - transform: translateZ(0); - opacity: 0; - width: calc(100% - 64px); - mask-image: linear-gradient(to bottom, black 0%, black 80%, transparent 100%); - -webkit-mask-image: linear-gradient( - to bottom, - black 0%, - black 80%, - transparent 100% - ); -} - -@media (max-width: 768px) { - .stickyHeader { - display: none; - } -} - -.right { - display: flex; - align-items: center; - gap: 24px; -} - -.name { - font-size: 24px; - color: var(--text-primary); - font-weight: 400; -} - -.version { - font-size: 14px; - color: var(--text-secondary); - font-weight: 500; -} - -.actions { - display: flex; - align-items: center; - gap: 16px; -} - -.versionLinks { - display: flex; - align-items: center; - - a { - width: 48px; - height: 48px; - display: flex; - align-items: center; - justify-content: center; - color: var(--secondary); - transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out; - border-radius: 48px; - - &:hover { - color: var(--primary); - background-color: var(--action); - } - } -} - -@media (max-width: 768px) { - .stickyHeader { - padding: 12px 16px; - } - - .right { - gap: 16px; - } - - .version { - font-size: 12px; - } -} - -@media (min-width: 768px) { - .stickyHeader { - width: calc(100% - 332px - 40px); - left: 332px; - right: 40px; - } -} diff --git a/docs-ui/src/components/StickyHeader/StickyHeader.tsx b/docs-ui/src/components/StickyHeader/StickyHeader.tsx deleted file mode 100644 index 804d759715..0000000000 --- a/docs-ui/src/components/StickyHeader/StickyHeader.tsx +++ /dev/null @@ -1,50 +0,0 @@ -'use client'; - -import { motion, useScroll, useTransform, circOut } from 'framer-motion'; -import { RiGithubLine, RiNpmjsLine } from '@remixicon/react'; -import { ThemeSelector } from '../Toolbar/theme'; -import { ThemeNameSelector } from '../Toolbar/theme-name'; -import { useCurrentPage } from '@/hooks/useCurrentPage'; -import styles from './StickyHeader.module.css'; - -export const StickyHeader = () => { - const { scrollY } = useScroll(); - const currentPage = useCurrentPage(); - - // Transform scroll position to opacity only - const opacity = useTransform(scrollY, [100, 200], [0, 1], { - clamp: false, - }); - - const yPos = useTransform(scrollY, [200, 500], [-60, 0], { - clamp: true, - ease: circOut, - }); - - return ( - -
{currentPage || 'Backstage UI'}
-
- - - -
-
- ); -}; diff --git a/docs-ui/src/components/Table/styles.module.css b/docs-ui/src/components/Table/styles.module.css index 5a5ebab450..8f38ac6979 100644 --- a/docs-ui/src/components/Table/styles.module.css +++ b/docs-ui/src/components/Table/styles.module.css @@ -17,7 +17,7 @@ padding: 12px 16px !important; border: none !important; text-align: left; - background-color: var(--panel) !important; + background-color: var(--bg) !important; font-size: 16px; & p { diff --git a/docs-ui/src/components/TableOfContents/TableOfContents.module.css b/docs-ui/src/components/TableOfContents/TableOfContents.module.css new file mode 100644 index 0000000000..7275c24520 --- /dev/null +++ b/docs-ui/src/components/TableOfContents/TableOfContents.module.css @@ -0,0 +1,93 @@ +.container { + position: sticky; + top: 24px; + max-height: calc(100vh - 48px); + overflow-y: auto; + padding: 16px 0; +} + +.list { + list-style: none; + padding: 0; + margin: 0; + position: relative; +} + +.list::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 2px; + background-color: var(--border); +} + +.indicator { + position: absolute; + left: 0; + width: 2px; + background-color: var(--primary); + transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1), + height 0.3s cubic-bezier(0.4, 0, 0.2, 1); + pointer-events: none; + z-index: 1; +} + +.item { + position: relative; + margin: 0; +} + +.itemNested { + padding-left: 16px; +} + +.link { + display: block; + width: 100%; + text-align: left; + background: none; + border: none; + padding: 6px 16px; + font-size: 0.875rem; + color: var(--text-secondary); + cursor: pointer; + transition: color 0.2s ease; + line-height: 1.4; + position: relative; +} + +.link:hover { + color: var(--text); +} + +.itemActive .link { + color: var(--primary); + font-weight: 500; +} + +/* Hide scrollbar for webkit browsers */ +.container::-webkit-scrollbar { + width: 4px; +} + +.container::-webkit-scrollbar-track { + background: transparent; +} + +.container::-webkit-scrollbar-thumb { + background: var(--border); + border-radius: 2px; +} + +.container::-webkit-scrollbar-thumb:hover { + background: var(--text-secondary); +} + +/* Responsive: hide on smaller screens */ +@media (max-width: 1280px) { + .container { + display: none; + } +} diff --git a/docs-ui/src/components/TableOfContents/TableOfContents.tsx b/docs-ui/src/components/TableOfContents/TableOfContents.tsx new file mode 100644 index 0000000000..d18265415b --- /dev/null +++ b/docs-ui/src/components/TableOfContents/TableOfContents.tsx @@ -0,0 +1,132 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { usePathname } from 'next/navigation'; +import styles from './TableOfContents.module.css'; + +interface Heading { + id: string; + text: string; + level: number; +} + +export function TableOfContents() { + const [headings, setHeadings] = useState([]); + const [activeId, setActiveId] = useState(''); + const [indicatorTop, setIndicatorTop] = useState(0); + const [indicatorHeight, setIndicatorHeight] = useState(0); + const pathname = usePathname(); + + useEffect(() => { + // Extract all H2 and H3 headings from the document + const elements = Array.from( + document.querySelectorAll('h2[id], h3[id]'), + ) as HTMLHeadingElement[]; + + const headingData: Heading[] = elements.map(element => ({ + id: element.id, + text: (element.textContent || '').replace('#', '').trim(), + level: parseInt(element.tagName.substring(1)), + })); + + setHeadings(headingData); + + // Set initial active heading (first visible heading or first heading) + if (headingData.length > 0) { + const viewportTop = window.scrollY + 100; // offset for header + const visibleHeading = elements.find(element => { + const rect = element.getBoundingClientRect(); + return rect.top + window.scrollY >= viewportTop - 200; + }); + setActiveId(visibleHeading?.id || headingData[0].id); + } + + // Set up IntersectionObserver to track visible headings + const observerOptions = { + rootMargin: '-80px 0px -80% 0px', + threshold: 1, + }; + + const observerCallback = (entries: IntersectionObserverEntry[]) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + setActiveId(entry.target.id); + } + }); + }; + + const observer = new IntersectionObserver( + observerCallback, + observerOptions, + ); + + elements.forEach(element => observer.observe(element)); + + return () => { + elements.forEach(element => observer.unobserve(element)); + }; + }, [pathname]); + + // Update indicator position when activeId changes + useEffect(() => { + if (activeId) { + const activeElement = document.querySelector( + `[data-toc-id="${activeId}"]`, + ) as HTMLElement; + if (activeElement) { + const list = activeElement.closest('ul'); + if (list) { + const listRect = list.getBoundingClientRect(); + const elementRect = activeElement.getBoundingClientRect(); + setIndicatorTop(elementRect.top - listRect.top); + setIndicatorHeight(elementRect.height); + } + } + } + }, [activeId, headings]); + + const handleClick = (id: string) => { + const element = document.getElementById(id); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + // Update URL without scrolling (already handled above) + window.history.pushState(null, '', `#${id}`); + } + }; + + if (headings.length === 0) { + return null; + } + + return ( + + ); +} diff --git a/docs-ui/src/components/TableOfContents/index.ts b/docs-ui/src/components/TableOfContents/index.ts new file mode 100644 index 0000000000..ffe4593ca7 --- /dev/null +++ b/docs-ui/src/components/TableOfContents/index.ts @@ -0,0 +1 @@ +export { TableOfContents } from './TableOfContents'; diff --git a/docs-ui/src/components/Toolbar/Toolbar.module.css b/docs-ui/src/components/Toolbar/Toolbar.module.css index f0e58f2edb..581fc599b3 100644 --- a/docs-ui/src/components/Toolbar/Toolbar.module.css +++ b/docs-ui/src/components/Toolbar/Toolbar.module.css @@ -1,76 +1,77 @@ .toolbar { - position: fixed; display: flex; - top: 0; - left: 32px; - right: 32px; - height: 112px; - z-index: 10; + height: 80px; align-items: center; justify-content: space-between; - padding-left: 0.25rem; -} + margin-bottom: 24px; -.left { - /* width: 296px; */ - display: flex; - align-items: center; - gap: 0.5rem; - padding-right: 20px; -} - -.right { - flex: 1; - display: flex; - align-items: center; - justify-content: flex-end; -} - -.actions { - display: none; -} - -.version { - display: none; -} - -.versionLinks { - display: flex; - align-items: center; - - a { - width: 48px; - height: 48px; - display: flex; - align-items: center; - justify-content: center; - color: var(--secondary); - transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out; - border-radius: 48px; - - &:hover { - color: var(--primary); - background-color: var(--action); - } - } -} - -@media (min-width: 600px) { - .actions { - display: flex; - align-items: center; - gap: 1rem; - } -} - -@media (min-width: 768px) { - .toolbar { + @media (min-width: 768px) { right: 40px; } } +.breadcrumb { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.875rem; + font-weight: 500; +} + +.logoMobile { + display: block; + + @media (min-width: 768px) { + display: none; + } +} + +.breadcrumbDesktop { + display: none; + + @media (min-width: 768px) { + display: flex; + align-items: center; + gap: 0.5rem; + } +} + +.breadcrumbLink { + color: var(--secondary); + text-decoration: none; + cursor: pointer; + + &:hover { + color: var(--primary); + text-decoration: underline; + transition: color 0.2s ease-in-out; + text-decoration-thickness: 1px; + text-underline-offset: 4px; + } +} + +.breadcrumbSeparator { + color: var(--secondary); + flex-shrink: 0; +} + +.breadcrumbCurrent { + color: var(--primary); +} + +.actions { + display: none; + + @media (min-width: 320px) { + display: flex; + display: flex; + align-items: center; + gap: 0.5rem; + } +} + @media (min-width: 820px) { - .right { + .content { justify-content: space-between; } @@ -79,18 +80,164 @@ align-items: center; justify-content: center; /* background-color: var(--action); */ - border: 1px solid var(--border2); - border-radius: 48px; - padding-inline: 20px; - color: var(--primary); - font-size: 0.875rem; - font-weight: 500; - height: 48px; } } -@media (min-width: 960px) { - .left { - width: 296px; +.bubble { + display: flex; + align-items: center; + justify-content: center; + background-color: var(--bg); + border: 1px solid var(--border); + border-radius: 32px; + padding-inline: 16px; + color: var(--primary); + font-size: 0.875rem; + font-weight: 500; + height: 32px; + cursor: pointer; + gap: 4px; + + &[data-selected] { + background-color: var(--action); + color: var(--primary); + } + + &:hover { + background-color: var(--action); + transition: background-color 0.2s ease-in-out; + } + + &[data-hide-tablet] { + display: none; + } + + @media (min-width: 1024px) { + &[data-hide-tablet] { + display: flex; + } + } +} + +.buttonGroup { + display: flex; + align-items: center; + gap: 4px; + border: 1px solid var(--border); + border-radius: 32px; + padding-inline: 4px; + height: 32px; + display: none; + + @media (min-width: 480px) { + display: flex; + } +} + +.buttonGroup button { + height: 24px; + background-color: var(--bg); + border: none; + border-radius: 28px; + padding-inline: 16px; + color: var(--primary); + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + + &[data-selected] { + background-color: var(--action); + color: var(--primary); + } + + &:hover { + background-color: var(--action); + transition: background-color 0.2s ease-in-out; + } +} + +.Popup { + box-sizing: border-box; + padding-block: 0.25rem; + border-radius: 0.375rem; + background-color: var(--bg); + color: var(--color-gray-900); + border: 1px solid var(--border); + padding-inline: 0.25rem; + transform-origin: var(--transform-origin); + transition: transform 150ms, opacity 150ms; + + &[data-starting-style], + &[data-ending-style] { + opacity: 0; + transform: scale(0.9); + } + + &[data-side='none'] { + transition: none; + transform: none; + opacity: 1; + } + + @media (prefers-color-scheme: light) { + outline: 1px solid var(--color-gray-200); + box-shadow: 0px 10px 15px -3px var(--color-gray-200), + 0px 4px 6px -4px var(--color-gray-200); + } + + @media (prefers-color-scheme: dark) { + outline: 1px solid var(--color-gray-300); + outline-offset: -1px; + } +} + +.Popup[data-trigger='Select'] { + min-width: var(--trigger-width); + + .ListBox { + display: block; + width: unset; + max-height: inherit; + min-height: unset; + border: none; + + .react-aria-Header { + padding-left: 1.571rem; + } + } + + .Item { + position: relative; + padding: 0 0.571rem 0 1.571rem; + height: 2rem; + display: flex; + align-items: center; + + &[data-focus-visible] { + outline: none; + } + + &[data-selected] { + font-weight: 600; + background: unset; + color: var(--text-color); + + &::before { + content: '✓'; + content: '✓' / ''; + alt: ' '; + position: absolute; + left: 4px; + } + } + + &[data-focused], + &[data-pressed] { + background: var(--bg); + color: var(--primary); + cursor: pointer; + } } } diff --git a/docs-ui/src/components/Toolbar/Toolbar.tsx b/docs-ui/src/components/Toolbar/Toolbar.tsx index 29570739f8..e7defd5e8a 100644 --- a/docs-ui/src/components/Toolbar/Toolbar.tsx +++ b/docs-ui/src/components/Toolbar/Toolbar.tsx @@ -1,52 +1,168 @@ 'use client'; -import { RiGithubLine, RiNpmjsLine } from '@remixicon/react'; -import { motion, useScroll, useTransform } from 'framer-motion'; -import { useRef } from 'react'; -import { Logo } from './Logo'; -import { ThemeSelector } from './theme'; -import { ThemeNameSelector } from './theme-name'; +import { + RiArrowDownSLine, + RiArrowRightSLine, + RiGithubLine, + RiMoonLine, + RiSunLine, +} from '@remixicon/react'; +import { + Button, + ListBox, + ListBoxItem, + Popover, + Select, + SelectValue, + ToggleButton, + ToggleButtonGroup, +} from 'react-aria-components'; import styles from './Toolbar.module.css'; +import { usePlayground } from '@/utils/playground-context'; +import { usePathname } from 'next/navigation'; +import Link from 'next/link'; +import { components, layoutComponents } from '@/utils/data'; +import { Logo } from '@/components/Sidebar/Logo'; interface ToolbarProps { version: string; } -export const Toolbar = ({ version }: ToolbarProps) => { - const containerRef = useRef(null); - const { scrollY } = useScroll(); +const themes = [ + { name: 'Backstage', value: 'backstage' }, + { name: 'Spotify', value: 'spotify' }, + { name: 'Custom theme', value: 'custom' }, +]; - // Transform scroll velocity to vertical movement - const y = useTransform(scrollY, [0, 100], [0, -20], { - clamp: false, - }); +export const Toolbar = ({ version }: ToolbarProps) => { + const { + selectedTheme, + setSelectedTheme, + selectedThemeName, + setSelectedThemeName, + } = usePlayground(); + + const pathname = usePathname(); + + // Determine breadcrumb content based on current path + const getBreadcrumb = () => { + const allComponents = [...components, ...layoutComponents]; + + // Root page + if (pathname === '/') { + return { section: null, title: 'Getting Started' }; + } + + // Components index page + if (pathname === '/components') { + return { section: null, title: 'Components' }; + } + + // Component detail pages + if (pathname?.startsWith('/components/')) { + const slug = pathname.split('/components/')[1]; + const component = allComponents.find(c => c.slug === slug); + return { + section: 'Components', + sectionLink: '/components', + title: component?.title || slug, + }; + } + + // Tokens page + if (pathname === '/tokens') { + return { section: null, title: 'Tokens' }; + } + + // Changelog page + if (pathname === '/changelog') { + return { section: null, title: 'Changelog' }; + } + + return { section: null, title: '' }; + }; + + const breadcrumb = getBreadcrumb(); return ( -
-
- -
- -
Version {version} - Alpha
-
- - - +
+
+
+
- +
+ {breadcrumb.section && breadcrumb.sectionLink ? ( + <> + + {breadcrumb.section} + + + + {breadcrumb.title} + + + ) : ( + {breadcrumb.title} + )} +
+
+
+ + + Version {version} + + + + + + + + + + +
); }; diff --git a/docs-ui/src/components/Toolbar/theme-name.module.css b/docs-ui/src/components/Toolbar/theme-name.module.css deleted file mode 100644 index 1e1943b886..0000000000 --- a/docs-ui/src/components/Toolbar/theme-name.module.css +++ /dev/null @@ -1,110 +0,0 @@ -.Select { - box-sizing: border-box; - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.75rem; - height: 3rem; - padding-left: 1.25rem; - padding-right: 1rem; - margin: 0; - outline: 0; - border: 1px solid var(--color-gray-200); - border-radius: 3rem; - font-family: inherit; - font-size: 1rem; - line-height: 1.5rem; - color: var(--color-gray-900); - cursor: pointer; - user-select: none; - background-color: var(--action); - - &:focus-visible { - outline: 2px solid var(--color-blue); - outline-offset: -1px; - } -} - -.Popup { - box-sizing: border-box; - padding-block: 0.25rem; - border-radius: 0.375rem; - background-color: var(--panel); - color: var(--color-gray-900); - border: 1px solid var(--border); - padding-inline: 0.25rem; - transform-origin: var(--transform-origin); - transition: transform 150ms, opacity 150ms; - - &[data-starting-style], - &[data-ending-style] { - opacity: 0; - transform: scale(0.9); - } - - &[data-side='none'] { - transition: none; - transform: none; - opacity: 1; - } - - @media (prefers-color-scheme: light) { - outline: 1px solid var(--color-gray-200); - box-shadow: 0px 10px 15px -3px var(--color-gray-200), - 0px 4px 6px -4px var(--color-gray-200); - } - - @media (prefers-color-scheme: dark) { - outline: 1px solid var(--color-gray-300); - outline-offset: -1px; - } -} - -.Popup[data-trigger='Select'] { - min-width: var(--trigger-width); - - .ListBox { - display: block; - width: unset; - max-height: inherit; - min-height: unset; - border: none; - - .react-aria-Header { - padding-left: 1.571rem; - } - } - - .Item { - position: relative; - padding: 0 0.571rem 0 1.571rem; - height: 2rem; - display: flex; - align-items: center; - - &[data-focus-visible] { - outline: none; - } - - &[data-selected] { - font-weight: 600; - background: unset; - color: var(--text-color); - - &::before { - content: '✓'; - content: '✓' / ''; - alt: ' '; - position: absolute; - left: 4px; - } - } - - &[data-focused], - &[data-pressed] { - background: var(--bg); - color: var(--primary); - cursor: pointer; - } - } -} diff --git a/docs-ui/src/components/Toolbar/theme-name.tsx b/docs-ui/src/components/Toolbar/theme-name.tsx deleted file mode 100644 index ae9e7f9f35..0000000000 --- a/docs-ui/src/components/Toolbar/theme-name.tsx +++ /dev/null @@ -1,44 +0,0 @@ -'use client'; - -import { - Button, - ListBox, - ListBoxItem, - Popover, - Select, - SelectValue, -} from 'react-aria-components'; -import styles from './theme-name.module.css'; -import { usePlayground } from '@/utils/playground-context'; -import { RiArrowDownSLine } from '@remixicon/react'; - -const themes = [ - { name: 'Backstage', value: 'backstage' }, - { name: 'Spotify', value: 'spotify' }, - { name: 'Custom theme', value: 'custom' }, -]; - -export const ThemeNameSelector = () => { - const { selectedThemeName, setSelectedThemeName } = usePlayground(); - - return ( - - ); -}; diff --git a/docs-ui/src/components/Toolbar/theme.module.css b/docs-ui/src/components/Toolbar/theme.module.css deleted file mode 100644 index c5490a72d7..0000000000 --- a/docs-ui/src/components/Toolbar/theme.module.css +++ /dev/null @@ -1,79 +0,0 @@ -.tabs { - border-radius: 0.375rem; - width: 100%; -} - -.tabsTheme { - width: 100px; - border-radius: 0.375rem; -} - -.list { - display: flex; - position: relative; - z-index: 0; - gap: 0.25rem; -} - -.tab { - display: flex; - align-items: center; - justify-content: center; - border: 0; - margin: 0; - outline: 0; - background: none; - appearance: none; - color: var(--secondary); - user-select: none; - flex: 1; - cursor: pointer; - width: 3rem; - height: 3rem; - - &[data-selected] { - color: var(--primary); - - & p { - color: var(--primary); - } - } - - @media (hover: hover) { - &:hover { - color: var(--primary); - } - } - - &:focus-visible { - position: relative; - - &::before { - content: ''; - position: absolute; - inset: 0.25rem 0; - border-radius: 0.25rem; - outline: 2px solid var(--action); - outline-offset: -1px; - } - } -} - -.tab p { - color: var(--secondary) !important; -} - -.indicator { - position: absolute; - z-index: -1; - left: 0; - top: 50%; - translate: var(--active-tab-left) -50%; - width: var(--active-tab-width); - height: 3rem; - border-radius: 3rem; - background-color: var(--action); - transition-property: translate, width; - transition-duration: 200ms; - transition-timing-function: ease-in-out; -} diff --git a/docs-ui/src/components/Toolbar/theme.tsx b/docs-ui/src/components/Toolbar/theme.tsx deleted file mode 100644 index 7ece7bfe7b..0000000000 --- a/docs-ui/src/components/Toolbar/theme.tsx +++ /dev/null @@ -1,28 +0,0 @@ -'use client'; - -import { Tabs } from '@base-ui-components/react/tabs'; -import { usePlayground } from '@/utils/playground-context'; -import styles from './theme.module.css'; -import { RiMoonLine, RiSunLine } from '@remixicon/react'; - -export const ThemeSelector = () => { - const { selectedTheme, setSelectedTheme } = usePlayground(); - - return ( - - - - - - - - - - ); -}; diff --git a/docs-ui/src/content/accordion.mdx b/docs-ui/src/content/accordion.mdx new file mode 100644 index 0000000000..2694f8d144 --- /dev/null +++ b/docs-ui/src/content/accordion.mdx @@ -0,0 +1,128 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { AccordionSnippet } from '@/snippets/stories-snippets'; +import { + accordionPropDefs, + accordionTriggerPropDefs, + accordionPanelPropDefs, + accordionGroupPropDefs, + accordionUsageSnippet, + accordionWithSubtitleSnippet, + accordionCustomTriggerSnippet, + accordionDefaultExpandedSnippet, + accordionGroupSingleOpenSnippet, + accordionGroupMultipleOpenSnippet, +} from './accordion.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={accordionUsageSnippet} +/> + +## Usage + + + +## API reference + +### Accordion + +Root container for the accordion. Renders a `
` element. + + + +### AccordionTrigger + +Trigger component with built-in animated chevron icon. Renders a heading element (defaults to `

`, configurable via `level` prop) wrapping a ``; + export const buttonAsLinkSnippet = `import { ButtonLink } from '@backstage/ui'; diff --git a/docs-ui/src/content/components/card.mdx b/docs-ui/src/content/card.mdx similarity index 100% rename from docs-ui/src/content/components/card.mdx rename to docs-ui/src/content/card.mdx diff --git a/docs-ui/src/content/components/card.props.ts b/docs-ui/src/content/card.props.ts similarity index 100% rename from docs-ui/src/content/components/card.props.ts rename to docs-ui/src/content/card.props.ts diff --git a/docs-ui/src/content/components/checkbox.mdx b/docs-ui/src/content/checkbox.mdx similarity index 100% rename from docs-ui/src/content/components/checkbox.mdx rename to docs-ui/src/content/checkbox.mdx diff --git a/docs-ui/src/content/components/checkbox.props.ts b/docs-ui/src/content/checkbox.props.ts similarity index 53% rename from docs-ui/src/content/components/checkbox.props.ts rename to docs-ui/src/content/checkbox.props.ts index c7ee69280e..ce0f1033ff 100644 --- a/docs-ui/src/content/components/checkbox.props.ts +++ b/docs-ui/src/content/checkbox.props.ts @@ -5,31 +5,32 @@ import { } from '@/utils/propDefs'; export const checkboxPropDefs: Record = { - label: { - type: 'string', - responsive: false, - }, - defaultChecked: { + children: { type: 'enum', - values: ['boolean', "'indeterminate'"], + values: ['React.ReactNode'], responsive: false, }, - checked: { - type: 'enum', - values: ['boolean', "'indeterminate'"], - responsive: false, - }, - onChange: { - type: 'enum', - values: ["(checked: boolean | 'indeterminate') => void"], - responsive: false, - }, - disabled: { + isSelected: { type: 'enum', values: ['boolean'], responsive: false, }, - required: { + defaultSelected: { + type: 'enum', + values: ['boolean'], + responsive: false, + }, + onChange: { + type: 'enum', + values: ['(isSelected: boolean) => void'], + responsive: false, + }, + isDisabled: { + type: 'enum', + values: ['boolean'], + responsive: false, + }, + isRequired: { type: 'enum', values: ['boolean'], responsive: false, @@ -48,13 +49,13 @@ export const checkboxPropDefs: Record = { export const checkboxUsageSnippet = `import { Checkbox } from '@backstage/ui'; -`; +Accept terms`; -export const checkboxDefaultSnippet = ``; +export const checkboxDefaultSnippet = `Accept terms and conditions`; -export const checkboxVariantsSnippet = ` - - - - -`; +export const checkboxVariantsSnippet = ` + Unchecked + Checked + Disabled + Checked & Disabled +`; diff --git a/docs-ui/src/content/components/avatar.props.ts b/docs-ui/src/content/components/avatar.props.ts deleted file mode 100644 index 8cc53eeff3..0000000000 --- a/docs-ui/src/content/components/avatar.props.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs'; -import type { PropDef } from '@/utils/propDefs'; - -export const avatarPropDefs: Record = { - src: { - type: 'string', - }, - name: { - type: 'string', - }, - size: { - type: 'enum', - values: ['small', 'medium', 'large'], - default: 'medium', - responsive: true, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const snippetUsage = `import { Avatar } from '@backstage/ui'; - -`; - -export const snippetSizes = ` - - - -`; - -export const snippetFallback = ``; diff --git a/docs-ui/src/content/components/collapsible.mdx b/docs-ui/src/content/components/collapsible.mdx deleted file mode 100644 index 948da323fe..0000000000 --- a/docs-ui/src/content/components/collapsible.mdx +++ /dev/null @@ -1,72 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { CodeBlock } from '@/components/CodeBlock'; -import { CollapsibleSnippet } from '@/snippets/stories-snippets'; -import { - collapsibleRootPropDefs, - collapsibleTriggerPropDefs, - collapsiblePanelPropDefs, - collapsibleUsageSnippet, - collapsibleDefaultSnippet, - collapsibleTriggerSnippet, - collapsibleOpenSnippet, -} from './collapsible.props'; -import { PageTitle } from '@/components/PageTitle'; -import { Theming } from '@/components/Theming'; -import { ChangelogComponent } from '@/components/ChangelogComponent'; - - - -} - code={collapsibleDefaultSnippet} -/> - -## Usage - - - -## API reference - -### Collapsible.Root - -Groups all parts of the collapsible. Renders a `
` element. - - - -### 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. - - - - - -### Collapsible.Panel - -A panel with the collapsible contents. Renders a `
` element. - - - -## Examples - -Open the panel by default by setting the `defaultOpen` prop to `true`. - -} - code={collapsibleOpenSnippet} -/> - - - - diff --git a/docs-ui/src/content/components/collapsible.props.ts b/docs-ui/src/content/components/collapsible.props.ts deleted file mode 100644 index 55e80f6689..0000000000 --- a/docs-ui/src/content/components/collapsible.props.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { - classNamePropDefs, - stylePropDefs, - renderPropDefs, - type PropDef, -} from '@/utils/propDefs'; - -export const collapsibleRootPropDefs: Record = { - defaultOpen: { - type: 'boolean', - default: 'false', - }, - open: { - type: 'boolean', - }, - onOpenChange: { - type: 'enum', - values: ['(open) => void'], - }, - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const collapsibleTriggerPropDefs: Record = { - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const collapsiblePanelPropDefs: Record = { - hiddenUntilFound: { - type: 'boolean', - default: 'false', - }, - keepMounted: { - type: 'boolean', - default: 'false', - }, - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const collapsibleUsageSnippet = `import { Collapsible } from '@backstage/ui'; - - - ( - - )} /> - Your content -`; - -export const collapsibleDefaultSnippet = ` - ( - - )} /> - - - It's the edge of the world and all of Western civilization - The sun may rise in the East, at least it settled in a final location - It's understood that Hollywood sells Californication - - -`; - -export const collapsibleTriggerSnippet = ` - )} /> - - - It's the edge of the world and all of Western civilization - The sun may rise in the East, at least it settled in a final location - It's understood that Hollywood sells Californication - - -`; diff --git a/docs-ui/src/content/components/container.mdx b/docs-ui/src/content/container.mdx similarity index 100% rename from docs-ui/src/content/components/container.mdx rename to docs-ui/src/content/container.mdx diff --git a/docs-ui/src/content/components/container.props.ts b/docs-ui/src/content/container.props.ts similarity index 100% rename from docs-ui/src/content/components/container.props.ts rename to docs-ui/src/content/container.props.ts diff --git a/docs-ui/src/content/components/dialog.mdx b/docs-ui/src/content/dialog.mdx similarity index 100% rename from docs-ui/src/content/components/dialog.mdx rename to docs-ui/src/content/dialog.mdx diff --git a/docs-ui/src/content/components/dialog.props.ts b/docs-ui/src/content/dialog.props.ts similarity index 100% rename from docs-ui/src/content/components/dialog.props.ts rename to docs-ui/src/content/dialog.props.ts diff --git a/docs-ui/src/content/components/flex.mdx b/docs-ui/src/content/flex.mdx similarity index 100% rename from docs-ui/src/content/components/flex.mdx rename to docs-ui/src/content/flex.mdx diff --git a/docs-ui/src/content/components/flex.props.ts b/docs-ui/src/content/flex.props.ts similarity index 100% rename from docs-ui/src/content/components/flex.props.ts rename to docs-ui/src/content/flex.props.ts diff --git a/docs-ui/src/content/components/grid.mdx b/docs-ui/src/content/grid.mdx similarity index 100% rename from docs-ui/src/content/components/grid.mdx rename to docs-ui/src/content/grid.mdx diff --git a/docs-ui/src/content/components/grid.props.ts b/docs-ui/src/content/grid.props.ts similarity index 100% rename from docs-ui/src/content/components/grid.props.ts rename to docs-ui/src/content/grid.props.ts diff --git a/docs-ui/src/content/components/header-page.mdx b/docs-ui/src/content/header-page.mdx similarity index 100% rename from docs-ui/src/content/components/header-page.mdx rename to docs-ui/src/content/header-page.mdx diff --git a/docs-ui/src/content/components/header-page.props.ts b/docs-ui/src/content/header-page.props.ts similarity index 100% rename from docs-ui/src/content/components/header-page.props.ts rename to docs-ui/src/content/header-page.props.ts diff --git a/docs-ui/src/content/components/header.mdx b/docs-ui/src/content/header.mdx similarity index 100% rename from docs-ui/src/content/components/header.mdx rename to docs-ui/src/content/header.mdx diff --git a/docs-ui/src/content/components/header.props.ts b/docs-ui/src/content/header.props.ts similarity index 100% rename from docs-ui/src/content/components/header.props.ts rename to docs-ui/src/content/header.props.ts diff --git a/docs-ui/src/content/components/link.mdx b/docs-ui/src/content/link.mdx similarity index 100% rename from docs-ui/src/content/components/link.mdx rename to docs-ui/src/content/link.mdx diff --git a/docs-ui/src/content/components/link.props.ts b/docs-ui/src/content/link.props.ts similarity index 100% rename from docs-ui/src/content/components/link.props.ts rename to docs-ui/src/content/link.props.ts diff --git a/docs-ui/src/content/components/menu.mdx b/docs-ui/src/content/menu.mdx similarity index 100% rename from docs-ui/src/content/components/menu.mdx rename to docs-ui/src/content/menu.mdx diff --git a/docs-ui/src/content/components/menu.props.ts b/docs-ui/src/content/menu.props.ts similarity index 100% rename from docs-ui/src/content/components/menu.props.ts rename to docs-ui/src/content/menu.props.ts diff --git a/docs-ui/src/content/components/password-field.mdx b/docs-ui/src/content/password-field.mdx similarity index 100% rename from docs-ui/src/content/components/password-field.mdx rename to docs-ui/src/content/password-field.mdx diff --git a/docs-ui/src/content/components/password-field.props.ts b/docs-ui/src/content/password-field.props.ts similarity index 100% rename from docs-ui/src/content/components/password-field.props.ts rename to docs-ui/src/content/password-field.props.ts diff --git a/docs-ui/src/content/components/radio-group.mdx b/docs-ui/src/content/radio-group.mdx similarity index 100% rename from docs-ui/src/content/components/radio-group.mdx rename to docs-ui/src/content/radio-group.mdx diff --git a/docs-ui/src/content/components/radio-group.props.ts b/docs-ui/src/content/radio-group.props.ts similarity index 100% rename from docs-ui/src/content/components/radio-group.props.ts rename to docs-ui/src/content/radio-group.props.ts diff --git a/docs-ui/src/content/components/search-field.mdx b/docs-ui/src/content/search-field.mdx similarity index 100% rename from docs-ui/src/content/components/search-field.mdx rename to docs-ui/src/content/search-field.mdx diff --git a/docs-ui/src/content/components/search-field.props.ts b/docs-ui/src/content/search-field.props.ts similarity index 100% rename from docs-ui/src/content/components/search-field.props.ts rename to docs-ui/src/content/search-field.props.ts diff --git a/docs-ui/src/content/components/select.mdx b/docs-ui/src/content/select.mdx similarity index 71% rename from docs-ui/src/content/components/select.mdx rename to docs-ui/src/content/select.mdx index 09a852e871..eb53e9ea35 100644 --- a/docs-ui/src/content/components/select.mdx +++ b/docs-ui/src/content/select.mdx @@ -11,6 +11,9 @@ import { selectDisabledSnippet, selectResponsiveSnippet, selectIconSnippet, + selectSearchableSnippet, + selectMultipleSnippet, + selectSearchableMultipleSnippet, } from './select.props'; import { PageTitle } from '@/components/PageTitle'; import { Theming } from '@/components/Theming'; @@ -87,6 +90,42 @@ Here's a view when the select is disabled. code={selectDisabledSnippet} /> +### Searchable + +Here's a view when the select has searchable filtering. + +} + code={selectSearchableSnippet} +/> + +### Multiple Selection + +Here's a view when the select allows multiple selections. + +} + code={selectMultipleSnippet} +/> + +### Searchable with Multiple Selection + +Here's a view when the select combines search and multiple selection. + +} + code={selectSearchableMultipleSnippet} +/> + ### Responsive Here's a view when the select is responsive. diff --git a/docs-ui/src/content/components/select.props.ts b/docs-ui/src/content/select.props.ts similarity index 59% rename from docs-ui/src/content/components/select.props.ts rename to docs-ui/src/content/select.props.ts index a93f448bd8..05f0d895c9 100644 --- a/docs-ui/src/content/components/select.props.ts +++ b/docs-ui/src/content/select.props.ts @@ -23,6 +23,12 @@ export const selectPropDefs: Record = { values: ['Array<{ value: string, label: string }>'], required: true, }, + selectionMode: { + type: 'enum', + values: ['single', 'multiple'], + default: 'single', + responsive: false, + }, placeholder: { type: 'string', default: 'Select an item', @@ -34,17 +40,23 @@ export const selectPropDefs: Record = { responsive: false, }, value: { - type: 'string', + type: 'enum', + values: ['string', 'string[]'], responsive: false, + description: + 'Selected value (controlled). String for single selection, array for multiple.', }, defaultValue: { - type: 'string', + type: 'enum', + values: ['string', 'string[]'], responsive: false, + description: + 'Initial value (uncontrolled). String for single selection, array for multiple.', }, size: { type: 'enum', values: ['small', 'medium'], - default: 'medium', + default: 'small', responsive: true, }, isOpen: { @@ -57,7 +69,7 @@ export const selectPropDefs: Record = { }, disabledKeys: { type: 'enum', - values: ['string[]'], + values: ['Iterable'], responsive: false, }, isDisabled: { @@ -72,14 +84,6 @@ export const selectPropDefs: Record = { type: 'boolean', responsive: false, }, - selectedKey: { - type: 'string', - responsive: false, - }, - defaultSelectedKey: { - type: 'string', - responsive: false, - }, onOpenChange: { type: 'enum', values: ['(isOpen: boolean) => void'], @@ -87,7 +91,19 @@ export const selectPropDefs: Record = { }, onSelectionChange: { type: 'enum', - values: ['(key: Key | null) => void'], + values: ['(key: Key | null) => void', '(keys: Selection) => void'], + responsive: false, + description: + 'Handler called when selection changes. Single mode: receives Key | null. Multiple mode: receives Selection.', + }, + searchable: { + type: 'boolean', + default: 'false', + responsive: false, + }, + searchPlaceholder: { + type: 'string', + default: 'Search...', responsive: false, }, ...classNamePropDefs, @@ -151,3 +167,45 @@ export const selectResponsiveSnippet = ``; + +export const selectMultipleSnippet = ``; diff --git a/docs-ui/src/content/components/skeleton.mdx b/docs-ui/src/content/skeleton.mdx similarity index 100% rename from docs-ui/src/content/components/skeleton.mdx rename to docs-ui/src/content/skeleton.mdx diff --git a/docs-ui/src/content/components/skeleton.props.ts b/docs-ui/src/content/skeleton.props.ts similarity index 100% rename from docs-ui/src/content/components/skeleton.props.ts rename to docs-ui/src/content/skeleton.props.ts diff --git a/docs-ui/src/content/components/switch.mdx b/docs-ui/src/content/switch.mdx similarity index 100% rename from docs-ui/src/content/components/switch.mdx rename to docs-ui/src/content/switch.mdx diff --git a/docs-ui/src/content/components/switch.props.ts b/docs-ui/src/content/switch.props.ts similarity index 100% rename from docs-ui/src/content/components/switch.props.ts rename to docs-ui/src/content/switch.props.ts diff --git a/docs-ui/src/content/components/table.mdx b/docs-ui/src/content/table.mdx similarity index 100% rename from docs-ui/src/content/components/table.mdx rename to docs-ui/src/content/table.mdx diff --git a/docs-ui/src/content/components/table.props.ts b/docs-ui/src/content/table.props.ts similarity index 99% rename from docs-ui/src/content/components/table.props.ts rename to docs-ui/src/content/table.props.ts index d46c6b8ea7..443526182e 100644 --- a/docs-ui/src/content/components/table.props.ts +++ b/docs-ui/src/content/table.props.ts @@ -2,7 +2,7 @@ import { classNamePropDefs, stylePropDefs, type PropDef, -} from '../../utils/propDefs'; +} from '@/utils/propDefs'; export const tablePropDefs: Record = { selectionBehavior: { diff --git a/docs-ui/src/content/components/tabs.mdx b/docs-ui/src/content/tabs.mdx similarity index 100% rename from docs-ui/src/content/components/tabs.mdx rename to docs-ui/src/content/tabs.mdx diff --git a/docs-ui/src/content/components/tabs.props.ts b/docs-ui/src/content/tabs.props.ts similarity index 100% rename from docs-ui/src/content/components/tabs.props.ts rename to docs-ui/src/content/tabs.props.ts diff --git a/docs-ui/src/content/components/tag-group.mdx b/docs-ui/src/content/tag-group.mdx similarity index 100% rename from docs-ui/src/content/components/tag-group.mdx rename to docs-ui/src/content/tag-group.mdx diff --git a/docs-ui/src/content/components/tag-group.props.ts b/docs-ui/src/content/tag-group.props.ts similarity index 100% rename from docs-ui/src/content/components/tag-group.props.ts rename to docs-ui/src/content/tag-group.props.ts diff --git a/docs-ui/src/content/components/text-field.mdx b/docs-ui/src/content/text-field.mdx similarity index 100% rename from docs-ui/src/content/components/text-field.mdx rename to docs-ui/src/content/text-field.mdx diff --git a/docs-ui/src/content/components/text-field.props.ts b/docs-ui/src/content/text-field.props.ts similarity index 100% rename from docs-ui/src/content/components/text-field.props.ts rename to docs-ui/src/content/text-field.props.ts diff --git a/docs-ui/src/content/components/text.mdx b/docs-ui/src/content/text.mdx similarity index 100% rename from docs-ui/src/content/components/text.mdx rename to docs-ui/src/content/text.mdx diff --git a/docs-ui/src/content/components/text.props.ts b/docs-ui/src/content/text.props.ts similarity index 100% rename from docs-ui/src/content/components/text.props.ts rename to docs-ui/src/content/text.props.ts diff --git a/docs-ui/src/content/components/tooltip.mdx b/docs-ui/src/content/tooltip.mdx similarity index 100% rename from docs-ui/src/content/components/tooltip.mdx rename to docs-ui/src/content/tooltip.mdx diff --git a/docs-ui/src/content/components/tooltip.props.ts b/docs-ui/src/content/tooltip.props.ts similarity index 100% rename from docs-ui/src/content/components/tooltip.props.ts rename to docs-ui/src/content/tooltip.props.ts diff --git a/docs-ui/src/content/visually-hidden.mdx b/docs-ui/src/content/visually-hidden.mdx new file mode 100644 index 0000000000..26a609b245 --- /dev/null +++ b/docs-ui/src/content/visually-hidden.mdx @@ -0,0 +1,51 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { VisuallyHiddenSnippet } from '@/snippets/stories-snippets'; +import { + visuallyHiddenPropDefs, + visuallyHiddenUsageSnippet, + visuallyHiddenDefaultSnippet, + visuallyHiddenExampleUsageSnippet, +} from './visually-hidden.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={visuallyHiddenDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Example Usage + +Here's an example of providing screen reader context for a list of links in a footer. + +} + code={visuallyHiddenExampleUsageSnippet} + open +/> + + + + diff --git a/docs-ui/src/content/visually-hidden.props.ts b/docs-ui/src/content/visually-hidden.props.ts new file mode 100644 index 0000000000..18a1c503d1 --- /dev/null +++ b/docs-ui/src/content/visually-hidden.props.ts @@ -0,0 +1,47 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const visuallyHiddenPropDefs: Record = { + children: { + type: 'enum', + values: ['ReactNode'], + responsive: false, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const visuallyHiddenUsageSnippet = `import { VisuallyHidden } from '@backstage/ui'; + + + This content is visually hidden but accessible to screen readers +`; + +export const visuallyHiddenDefaultSnippet = ` + + This text is followed by a paragraph that is visually hidden but + accessible to screen readers. Try using a screen reader to hear it, or + inspect the DOM to see it's there. + + + This content is visually hidden but accessible to screen readers + +`; + +export const visuallyHiddenExampleUsageSnippet = ` + + Footer links + + + About us + + + Jobs + + + Terms and Conditions + +`; diff --git a/docs-ui/src/css/globals.css b/docs-ui/src/css/globals.css index fa1a61eb4f..dcc348a9ee 100644 --- a/docs-ui/src/css/globals.css +++ b/docs-ui/src/css/globals.css @@ -1,10 +1,9 @@ :root { - --bg: #f4f4f4; - --panel: #fff; - --panel-hover: #fafafa; + --bg: #ffffff; + --bg-hover: #fafafa; --primary: #000; --secondary: #929292; - --action: #fff; + --action: #f3f3f3; --link: #4f5ce0; --font-regular: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', @@ -16,12 +15,15 @@ --border: #e5e5e5; --border2: #cdcdcd; --surface-1: #f4f4f4; + --code-bg: #3e444f; + --code-title: #505865; } [data-theme-mode='dark'] { - --bg: #000; - --panel: #181818; - --panel-hover: #202020; + --bg: #000000; + --bg-hover: #202020; + --code-bg: #202020; + --code-title: #292929; --primary: #fff; --secondary: #818181; --action: #202020; diff --git a/docs-ui/src/css/mdx.module.css b/docs-ui/src/css/mdx.module.css index 6a65995003..7cc2422ecd 100644 --- a/docs-ui/src/css/mdx.module.css +++ b/docs-ui/src/css/mdx.module.css @@ -49,3 +49,27 @@ .a:hover { text-decoration: underline; } + +.headingWithAnchor { + position: relative; + scroll-margin-top: 80px; +} + +.anchorLink { + color: inherit; + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 0.5rem; +} + +.anchorHash { + opacity: 0; + transition: opacity 0.2s; + font-size: 0.8em; + color: var(--text-secondary); +} + +.anchorLink:hover .anchorHash { + opacity: 1; +} diff --git a/docs-ui/src/mdx-components.tsx b/docs-ui/src/mdx-components.tsx index 75dbc81df8..bae798bf7c 100644 --- a/docs-ui/src/mdx-components.tsx +++ b/docs-ui/src/mdx-components.tsx @@ -4,10 +4,61 @@ import Image, { ImageProps } from 'next/image'; import { CodeBlock } from '@/components/CodeBlock'; import styles from './css/mdx.module.css'; +// Utility function to generate slug from heading text +function slugify(text: string): string { + return text + .toString() + .toLocaleLowerCase('en-US') + .trim() + .replace(/\s+/g, '-') + .replace(/[^\w\-]+/g, '') + .replace(/\-\-+/g, '-') + .replace(/^-+/, '') + .replace(/-+$/, ''); +} + +// Component for heading with anchor link +function HeadingWithAnchor({ + level, + children, + className, +}: { + level: number; + children: ReactNode; + className: string; +}) { + const text = + typeof children === 'string' + ? children + : Array.isArray(children) + ? children.join('') + : ''; + const id = slugify(text); + + const Tag = `h${level}` as keyof JSX.IntrinsicElements; + + return ( + + + {children} + # + + + ); +} + export const formattedMDXComponents: MDXComponents = { h1: ({ children }) =>

{children as ReactNode}

, - h2: ({ children }) =>

{children as ReactNode}

, - h3: ({ children }) =>

{children as ReactNode}

, + h2: ({ children }) => ( + + {children as ReactNode} + + ), + h3: ({ children }) => ( + + {children as ReactNode} + + ), p: ({ children }) =>

{children as ReactNode}

, a: ({ children, href }) => ( @@ -27,7 +78,7 @@ export const formattedMDXComponents: MDXComponents = { p.slug === slug); - if (overviewPage) { - return overviewPage.title; - } - - // Search in core concepts array - const coreConcept = coreConcepts.find(c => c.slug === slug); - if (coreConcept) { - return coreConcept.title; - } - // Search in components array const component = components.find(c => c.slug === slug); if (component) { diff --git a/docs-ui/src/utils/playground-context.tsx b/docs-ui/src/utils/playground-context.tsx index 2f8ffbaee4..a1cee6ecba 100644 --- a/docs-ui/src/utils/playground-context.tsx +++ b/docs-ui/src/utils/playground-context.tsx @@ -16,8 +16,8 @@ const PlaygroundContext = createContext<{ setSelectedScreenSizes: (screenSizes: string[]) => void; selectedComponents: string[]; setSelectedComponents: (components: string[]) => void; - selectedTheme: Theme; - setSelectedTheme: (theme: Theme) => void; + selectedTheme: Set; + setSelectedTheme: (keys: Set) => void; selectedThemeName: ThemeName; setSelectedThemeName: (themeName: ThemeName) => void; }>({ @@ -25,7 +25,7 @@ const PlaygroundContext = createContext<{ setSelectedScreenSizes: () => {}, selectedComponents: [], setSelectedComponents: () => {}, - selectedTheme: 'light', + selectedTheme: new Set(['light']), setSelectedTheme: () => {}, selectedThemeName: 'backstage', setSelectedThemeName: () => {}, @@ -40,16 +40,24 @@ export const PlaygroundProvider = ({ children }: { children: ReactNode }) => { const [selectedComponents, setSelectedComponents] = useState( components.map(component => component.slug), ); - const [selectedTheme, setSelectedTheme] = useState('light'); + const [selectedTheme, setSelectedTheme] = useState>( + new Set(['light']), + ); const [selectedThemeName, setSelectedThemeName] = useState('backstage'); // Load saved theme from localStorage after hydration useEffect(() => { if (isBrowser) { - const savedTheme = localStorage.getItem('theme-mode') as Theme; - if (savedTheme) { - setSelectedTheme(savedTheme); + const savedThemeString = localStorage.getItem('theme-mode'); + if (savedThemeString) { + // Parse the comma-separated string back into a Set + const themeArray = savedThemeString + .split(',') + .filter(Boolean) as Theme[]; + setSelectedTheme(new Set(themeArray)); + } else { + setSelectedTheme(new Set(['light'])); } } }, [isBrowser]); @@ -68,9 +76,9 @@ export const PlaygroundProvider = ({ children }: { children: ReactNode }) => { if (isBrowser) { document.documentElement.setAttribute( 'data-theme-mode', - selectedTheme || 'light', + Array.from(selectedTheme).join(','), ); - localStorage.setItem('theme-mode', selectedTheme || 'light'); + localStorage.setItem('theme-mode', Array.from(selectedTheme).join(',')); } }, [selectedTheme, isBrowser]); diff --git a/docs-ui/yarn.lock b/docs-ui/yarn.lock index 538b4947b2..480f7592f8 100644 --- a/docs-ui/yarn.lock +++ b/docs-ui/yarn.lock @@ -23,10 +23,51 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.21.0": - version: 7.28.3 - resolution: "@babel/runtime@npm:7.28.3" - checksum: 10/f2415e4dbface7496f6fc561d640b44be203071fb0dfb63fbe338c7d2d2047419cb054ef13d1ebb8fc11e35d2b55aa3045def4b985e8b82aea5d7e58e1133e52 +"@babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/runtime@npm:7.28.4" + checksum: 10/6c9a70452322ea80b3c9b2a412bcf60771819213a67576c8cec41e88a95bb7bf01fc983754cda35dc19603eef52df22203ccbf7777b9d6316932f9fb77c25163 + languageName: node + linkType: hard + +"@base-ui-components/react@npm:^1.0.0-beta.4": + version: 1.0.0-beta.4 + resolution: "@base-ui-components/react@npm:1.0.0-beta.4" + dependencies: + "@babel/runtime": "npm:^7.28.4" + "@base-ui-components/utils": "npm:0.1.2" + "@floating-ui/react-dom": "npm:^2.1.6" + "@floating-ui/utils": "npm:^0.2.10" + reselect: "npm:^5.1.1" + tabbable: "npm:^6.2.0" + use-sync-external-store: "npm:^1.5.0" + peerDependencies: + "@types/react": ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/d2c6a779aaefa3454cc130244e839f0428460997f3ca8bbcd9636056bc5a4c77436cc0ceac064f34bdc7cb01489a4cbc4d8b0bf9668a023fa754e5a24bd3af4e + languageName: node + linkType: hard + +"@base-ui-components/utils@npm:0.1.2": + version: 0.1.2 + resolution: "@base-ui-components/utils@npm:0.1.2" + dependencies: + "@babel/runtime": "npm:^7.28.4" + "@floating-ui/utils": "npm:^0.2.10" + reselect: "npm:^5.1.1" + use-sync-external-store: "npm:^1.5.0" + peerDependencies: + "@types/react": ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/b8408f5ad55886f793fb7580ffe2bb9565ff0713bec324f726b88ee1d135d75b26a1312338b19af743adf52e5b9d46892a47fb225e6abfe1077e75d32e88fb6e languageName: node linkType: hard @@ -138,14 +179,14 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0, @codemirror/view@npm:^6.34.4, @codemirror/view@npm:^6.35.0": - version: 6.38.1 - resolution: "@codemirror/view@npm:6.38.1" + version: 6.38.6 + resolution: "@codemirror/view@npm:6.38.6" dependencies: "@codemirror/state": "npm:^6.5.0" crelt: "npm:^1.0.6" style-mod: "npm:^4.1.0" w3c-keyname: "npm:^2.2.4" - checksum: 10/e0c5a365608749dd096ba7a930c8393f316bf4c2cacd1465a47a057d0a9f9868ff372a0bb6eb696c926f88411139f79a97a05f8c884bcc380145445cc61e68c8 + checksum: 10/5a047337a98de111817ce8c8d39e6429c90ca0b0a4d2678d6e161e9e5961b1d476a891f447ab7a05cac395d4a93530e7c68bedd93191285265f0742a308ad00b languageName: node linkType: hard @@ -401,6 +442,44 @@ __metadata: languageName: node linkType: hard +"@floating-ui/core@npm:^1.7.3": + version: 1.7.3 + resolution: "@floating-ui/core@npm:1.7.3" + dependencies: + "@floating-ui/utils": "npm:^0.2.10" + checksum: 10/a8952ff2673ddf28f12feeb86d90c54949e45bcb1af5758b7672850ac0dadb36d4bd61aa45dad1b6a35ba40d4756d3573afac6610b90502639d7266b91e0864e + languageName: node + linkType: hard + +"@floating-ui/dom@npm:^1.7.4": + version: 1.7.4 + resolution: "@floating-ui/dom@npm:1.7.4" + dependencies: + "@floating-ui/core": "npm:^1.7.3" + "@floating-ui/utils": "npm:^0.2.10" + checksum: 10/d3d6a23e7b9804ba56338c7c666590258683af14b6026270d32afc1202f72b5b82cca359004bdc7830bf2463a045da6c7bd4e7d5351218cf270ff94206197971 + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^2.1.6": + version: 2.1.6 + resolution: "@floating-ui/react-dom@npm:2.1.6" + dependencies: + "@floating-ui/dom": "npm:^1.7.4" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10/fbfd3319b42edb9c156e4e872f500d2edb112bc9cfd1b45892bff16ccf21c2484ddc9c416f7631c2aaaadec1b2f98b205db8a3f89eb78ca870905fcfe3917c35 + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.10": + version: 0.2.10 + resolution: "@floating-ui/utils@npm:0.2.10" + checksum: 10/b635ea865a8be2484b608b7157f5abf9ed439f351011a74b7e988439e2898199a9a8b790f52291e05bdcf119088160dc782d98cff45cc98c5a271bc6f51327ae + languageName: node + linkType: hard + "@humanwhocodes/config-array@npm:^0.13.0": version: 0.13.0 resolution: "@humanwhocodes/config-array@npm:0.13.0" @@ -650,10 +729,10 @@ __metadata: languageName: node linkType: hard -"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.2, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.2.0": - version: 1.2.3 - resolution: "@lezer/common@npm:1.2.3" - checksum: 10/dad24e353e4e67d88b203191361ca1dff26c01c2b7b4ae829b668a1d115929334d077217367683e39180c0556510ed2066ea8ddba2b079be7c08a7152208cc87 +"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.2, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.2.0, @lezer/common@npm:^1.3.0": + version: 1.3.0 + resolution: "@lezer/common@npm:1.3.0" + checksum: 10/8e195a8e426bc18d4339b3f2a1a7ad39c3b2cfa740c7108657a241985f63bdee5255a5f5cf8d863b878881744288bcb679d16170f0e5bcebb141188b53cfd8c0 languageName: node linkType: hard @@ -669,11 +748,11 @@ __metadata: linkType: hard "@lezer/highlight@npm:^1.0.0, @lezer/highlight@npm:^1.2.1": - version: 1.2.1 - resolution: "@lezer/highlight@npm:1.2.1" + version: 1.2.3 + resolution: "@lezer/highlight@npm:1.2.3" dependencies: - "@lezer/common": "npm:^1.0.0" - checksum: 10/fec3082419ee87fb265039b680fbac6796f862d8e3042dcb860e8c5a34291503a74927302b568ff1a626f0d2b5cf8dae02a51cfd200084eb329e5fd1236c3163 + "@lezer/common": "npm:^1.3.0" + checksum: 10/8f787d464f8a036f117a0b23e73ac034d224a57d72501c6559089098a28f127c9e495b90ac7d132acc86199e0b64d4c038f75f9293a37c7c61add52fa1acdb4e languageName: node linkType: hard @@ -705,8 +784,8 @@ __metadata: linkType: hard "@mdx-js/loader@npm:^3.1.0": - version: 3.1.0 - resolution: "@mdx-js/loader@npm:3.1.0" + version: 3.1.1 + resolution: "@mdx-js/loader@npm:3.1.1" dependencies: "@mdx-js/mdx": "npm:^3.0.0" source-map: "npm:^0.7.0" @@ -715,18 +794,19 @@ __metadata: peerDependenciesMeta: webpack: optional: true - checksum: 10/983b8d4949f4d214a17f4ad8597a50de36ace75e93292d2493b5fb6077d69d6abc8230b62f88b818c04f12a01d281d63edb6a0738937f7e259406a73ce998134 + checksum: 10/b78afe06e49b5c0bec9e5b232fbc874ffa721ff6b022bdaa7a29e2b5a44fa9f8282aa2b34f74701ca0b8750b33a775cd3182aaba5202e209f3d66961600c930f languageName: node linkType: hard -"@mdx-js/mdx@npm:^3.0.0, @mdx-js/mdx@npm:^3.1.0": - version: 3.1.0 - resolution: "@mdx-js/mdx@npm:3.1.0" +"@mdx-js/mdx@npm:^3.0.0, @mdx-js/mdx@npm:^3.1.1": + version: 3.1.1 + resolution: "@mdx-js/mdx@npm:3.1.1" dependencies: "@types/estree": "npm:^1.0.0" "@types/estree-jsx": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" "@types/mdx": "npm:^2.0.0" + acorn: "npm:^8.0.0" collapse-white-space: "npm:^2.0.0" devlop: "npm:^1.0.0" estree-util-is-identifier-name: "npm:^3.0.0" @@ -747,19 +827,19 @@ __metadata: unist-util-stringify-position: "npm:^4.0.0" unist-util-visit: "npm:^5.0.0" vfile: "npm:^6.0.0" - checksum: 10/4bd4e1160e2b2bc9ea2b5b93246ce0e34a11ac5fd420ec025e82fb1120a72b80025d9cb205cce6394bb5f0013f209b9ea453cbda4c0ca4f97a2169df60084742 + checksum: 10/b871da2497f6e0f11da1574fe772a50b09b7c177de8df0f821f708bf162febe76c01a572a5c68e860960189209fd66f768c2e747fdb3a1f497c5c32e11890c11 languageName: node linkType: hard -"@mdx-js/react@npm:^3.1.0": - version: 3.1.0 - resolution: "@mdx-js/react@npm:3.1.0" +"@mdx-js/react@npm:^3.1.0, @mdx-js/react@npm:^3.1.1": + version: 3.1.1 + resolution: "@mdx-js/react@npm:3.1.1" dependencies: "@types/mdx": "npm:^2.0.0" peerDependencies: "@types/react": ">=16" react: ">=16" - checksum: 10/cf89d6392c76091622fb647f205e1ab5cbdf5edd4401dde7092138cefc9fbb6d61428aa63557de0bccca3695d5a8854dd4a93b34a27cb8e27369da7eaeaa3e73 + checksum: 10/52a740e2f37761694fa94d4704b7825084b4055616a95c8b8f4c1676190d399ddc5cdbb399ffc45b550beecd30497a7224c2e5b05bf43ecb668c7473641037d1 languageName: node linkType: hard @@ -1990,7 +2070,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.2": +"chalk@npm:^4.0.0": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -2061,14 +2141,10 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^8.0.1": - version: 8.0.1 - resolution: "cliui@npm:8.0.1" - dependencies: - string-width: "npm:^4.2.0" - strip-ansi: "npm:^6.0.1" - wrap-ansi: "npm:^7.0.0" - checksum: 10/eaa5561aeb3135c2cddf7a3b3f562fc4238ff3b3fc666869ef2adf264be0f372136702f16add9299087fb1907c2e4ec5dbfe83bd24bce815c70a80c6c1a2e950 +"clsx@npm:^2.1.1": + version: 2.1.1 + resolution: "clsx@npm:2.1.1" + checksum: 10/cdfb57fa6c7649bbff98d9028c2f0de2f91c86f551179541cf784b1cfdc1562dcb951955f46d54d930a3879931a980e32a46b598acaea274728dbe068deca919 languageName: node linkType: hard @@ -2144,26 +2220,6 @@ __metadata: languageName: node linkType: hard -"concurrently@npm:^8.2.2": - version: 8.2.2 - resolution: "concurrently@npm:8.2.2" - dependencies: - chalk: "npm:^4.1.2" - date-fns: "npm:^2.30.0" - lodash: "npm:^4.17.21" - rxjs: "npm:^7.8.1" - shell-quote: "npm:^1.8.1" - spawn-command: "npm:0.0.2" - supports-color: "npm:^8.1.1" - tree-kill: "npm:^1.2.2" - yargs: "npm:^17.7.2" - bin: - conc: dist/bin/concurrently.js - concurrently: dist/bin/concurrently.js - checksum: 10/dcb1aa69d9c611a7bda9d4fc0fe1e388f971d1744acec7e0d52dffa2ef55743f1266ec9292f414c5789b9f61734b3fce772bd005d4de9564a949fb121b97bae1 - languageName: node - linkType: hard - "crelt@npm:^1.0.5, crelt@npm:^1.0.6": version: 1.0.6 resolution: "crelt@npm:1.0.6" @@ -2229,15 +2285,6 @@ __metadata: languageName: node linkType: hard -"date-fns@npm:^2.30.0": - version: 2.30.0 - resolution: "date-fns@npm:2.30.0" - dependencies: - "@babel/runtime": "npm:^7.21.0" - checksum: 10/70b3e8ea7aaaaeaa2cd80bd889622a4bcb5d8028b4de9162cbcda359db06e16ff6e9309e54eead5341e71031818497f19aaf9839c87d1aba1e27bb4796e758a9 - languageName: node - linkType: hard - "debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0": version: 4.4.1 resolution: "debug@npm:4.4.1" @@ -2331,6 +2378,7 @@ __metadata: version: 0.0.0-use.local resolution: "docs-ui@workspace:." dependencies: + "@base-ui-components/react": "npm:^1.0.0-beta.4" "@codemirror/lang-sass": "npm:^6.0.2" "@codemirror/view": "npm:^6.34.4" "@lezer/highlight": "npm:^1.2.1" @@ -2347,7 +2395,7 @@ __metadata: "@uiw/codemirror-themes": "npm:^4.23.7" "@uiw/react-codemirror": "npm:^4.23.7" chokidar: "npm:^3.6.0" - concurrently: "npm:^8.2.2" + clsx: "npm:^2.1.1" eslint: "npm:^8" eslint-config-next: "npm:15.3.4" html-react-parser: "npm:^5.2.5" @@ -2754,13 +2802,6 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.1.1": - version: 3.2.0 - resolution: "escalade@npm:3.2.0" - checksum: 10/9d7169e3965b2f9ae46971afa392f6e5a25545ea30f2e2dd99c9b0a95a3f52b5653681a84f5b2911a413ddad2d7a93d3514165072f349b5ffc59c75a899970d6 - languageName: node - linkType: hard - "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -3270,11 +3311,11 @@ __metadata: languageName: node linkType: hard -"framer-motion@npm:^12.23.12": - version: 12.23.12 - resolution: "framer-motion@npm:12.23.12" +"framer-motion@npm:^12.23.24": + version: 12.23.24 + resolution: "framer-motion@npm:12.23.24" dependencies: - motion-dom: "npm:^12.23.12" + motion-dom: "npm:^12.23.23" motion-utils: "npm:^12.23.6" tslib: "npm:^2.4.0" peerDependencies: @@ -3288,7 +3329,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 10/c15af3dc22476bf10d7509b9a336d113ed0fbeba57fca81ce5a6bf07f0d659ebc3588c3a839475cbdfc9601b64e2fc7551911e1c806dd2b896603c8a2c0c3870 + checksum: 10/c46015626d140557f3f225ffeaea14146988a42a99b33e46e3efbab88814343867a63014544169283b9518e1a3abed231ccefd890e601cf66b6c43425b0465e2 languageName: node linkType: hard @@ -3355,13 +3396,6 @@ __metadata: languageName: node linkType: hard -"get-caller-file@npm:^2.0.5": - version: 2.0.5 - resolution: "get-caller-file@npm:2.0.5" - checksum: 10/b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 - languageName: node - linkType: hard - "get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0": version: 1.3.0 resolution: "get-intrinsic@npm:1.3.0" @@ -3641,20 +3675,20 @@ __metadata: linkType: hard "html-react-parser@npm:^5.2.5": - version: 5.2.6 - resolution: "html-react-parser@npm:5.2.6" + version: 5.2.8 + resolution: "html-react-parser@npm:5.2.8" dependencies: domhandler: "npm:5.0.3" html-dom-parser: "npm:5.1.1" react-property: "npm:2.0.2" - style-to-js: "npm:1.1.17" + style-to-js: "npm:1.1.19" peerDependencies: "@types/react": 0.14 || 15 || 16 || 17 || 18 || 19 react: 0.14 || 15 || 16 || 17 || 18 || 19 peerDependenciesMeta: "@types/react": optional: true - checksum: 10/be2903fd932d44ff6cae66bd18b025d318879e16eb1e67c0ae6dc640e5c77509da41b61948c0d404a43b5362b57b7cfa3963df242b9773d4c7a16f410db7f2ac + checksum: 10/492d44f65c2a8647bb7d6db3865363739a00696687024b978f5f5e29475c40bd470c91e9ddefe0f1a846c85761f046e9a92fa3fe0e5581df43ac587787703b31 languageName: node linkType: hard @@ -3761,10 +3795,10 @@ __metadata: languageName: node linkType: hard -"inline-style-parser@npm:0.2.4": - version: 0.2.4 - resolution: "inline-style-parser@npm:0.2.4" - checksum: 10/80814479d1f3c9cbd102f9de4cd6558cf43cc2e48640e81c4371c3634f1e8b6dfeb2f21063cfa31d46cc83e834c20cd59ed9eeed9bfd45ef5bc02187ad941faf +"inline-style-parser@npm:0.2.6": + version: 0.2.6 + resolution: "inline-style-parser@npm:0.2.6" + checksum: 10/0be8356fcd766b7b170991293c9ad953f057ac9719960f51f4eb54af1a79c34638f591691f2ab43f57bef2e28e9c1239b8ae5f6b72bff2c652f828ccc621c08c languageName: node linkType: hard @@ -4275,92 +4309,102 @@ __metadata: languageName: node linkType: hard -"lightningcss-darwin-arm64@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-darwin-arm64@npm:1.30.1" +"lightningcss-android-arm64@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-android-arm64@npm:1.30.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-arm64@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-darwin-arm64@npm:1.30.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"lightningcss-darwin-x64@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-darwin-x64@npm:1.30.1" +"lightningcss-darwin-x64@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-darwin-x64@npm:1.30.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"lightningcss-freebsd-x64@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-freebsd-x64@npm:1.30.1" +"lightningcss-freebsd-x64@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-freebsd-x64@npm:1.30.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"lightningcss-linux-arm-gnueabihf@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-linux-arm-gnueabihf@npm:1.30.1" +"lightningcss-linux-arm-gnueabihf@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.30.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"lightningcss-linux-arm64-gnu@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-linux-arm64-gnu@npm:1.30.1" +"lightningcss-linux-arm64-gnu@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-linux-arm64-gnu@npm:1.30.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"lightningcss-linux-arm64-musl@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-linux-arm64-musl@npm:1.30.1" +"lightningcss-linux-arm64-musl@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-linux-arm64-musl@npm:1.30.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"lightningcss-linux-x64-gnu@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-linux-x64-gnu@npm:1.30.1" +"lightningcss-linux-x64-gnu@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-linux-x64-gnu@npm:1.30.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"lightningcss-linux-x64-musl@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-linux-x64-musl@npm:1.30.1" +"lightningcss-linux-x64-musl@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-linux-x64-musl@npm:1.30.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"lightningcss-win32-arm64-msvc@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-win32-arm64-msvc@npm:1.30.1" +"lightningcss-win32-arm64-msvc@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-win32-arm64-msvc@npm:1.30.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"lightningcss-win32-x64-msvc@npm:1.30.1": - version: 1.30.1 - resolution: "lightningcss-win32-x64-msvc@npm:1.30.1" +"lightningcss-win32-x64-msvc@npm:1.30.2": + version: 1.30.2 + resolution: "lightningcss-win32-x64-msvc@npm:1.30.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "lightningcss@npm:^1.28.2": - version: 1.30.1 - resolution: "lightningcss@npm:1.30.1" + version: 1.30.2 + resolution: "lightningcss@npm:1.30.2" dependencies: detect-libc: "npm:^2.0.3" - lightningcss-darwin-arm64: "npm:1.30.1" - lightningcss-darwin-x64: "npm:1.30.1" - lightningcss-freebsd-x64: "npm:1.30.1" - lightningcss-linux-arm-gnueabihf: "npm:1.30.1" - lightningcss-linux-arm64-gnu: "npm:1.30.1" - lightningcss-linux-arm64-musl: "npm:1.30.1" - lightningcss-linux-x64-gnu: "npm:1.30.1" - lightningcss-linux-x64-musl: "npm:1.30.1" - lightningcss-win32-arm64-msvc: "npm:1.30.1" - lightningcss-win32-x64-msvc: "npm:1.30.1" + lightningcss-android-arm64: "npm:1.30.2" + lightningcss-darwin-arm64: "npm:1.30.2" + lightningcss-darwin-x64: "npm:1.30.2" + lightningcss-freebsd-x64: "npm:1.30.2" + lightningcss-linux-arm-gnueabihf: "npm:1.30.2" + lightningcss-linux-arm64-gnu: "npm:1.30.2" + lightningcss-linux-arm64-musl: "npm:1.30.2" + lightningcss-linux-x64-gnu: "npm:1.30.2" + lightningcss-linux-x64-musl: "npm:1.30.2" + lightningcss-win32-arm64-msvc: "npm:1.30.2" + lightningcss-win32-x64-msvc: "npm:1.30.2" dependenciesMeta: + lightningcss-android-arm64: + optional: true lightningcss-darwin-arm64: optional: true lightningcss-darwin-x64: @@ -4381,7 +4425,7 @@ __metadata: optional: true lightningcss-win32-x64-msvc: optional: true - checksum: 10/6c921135216cc498dfcb87e35dffe8432e99306cbd58009c598b1daf20c81cc14535abbd4c1066e5d1faf4080ed44a2995e8ecc343633db4897a2d041b76fb05 + checksum: 10/d6cc06d9bac295589a49446e9c45a241dfa16f4f81a7318c26cbc0be3e189003ec0da5d9a0fd9bdffc63a3ce05878cc7329277eaac77a826e8b68c73dc96cfda languageName: node linkType: hard @@ -4401,13 +4445,6 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 - languageName: node - linkType: hard - "longest-streak@npm:^3.0.0": version: 3.1.0 resolution: "longest-streak@npm:3.1.0" @@ -5071,12 +5108,12 @@ __metadata: languageName: node linkType: hard -"motion-dom@npm:^12.23.12": - version: 12.23.12 - resolution: "motion-dom@npm:12.23.12" +"motion-dom@npm:^12.23.23": + version: 12.23.23 + resolution: "motion-dom@npm:12.23.23" dependencies: motion-utils: "npm:^12.23.6" - checksum: 10/e13cbd1f32ad30dc642ebc83f7f35d0fb76c4d93902daebdbbea2cdb85bb07481fb4fe315b3e2c899076dab5490fb611ff803c334b336bc4fcd59b9a1aa6d7ff + checksum: 10/6bec34c28b478622bd23ce919c0d64e7f372cbc3f88e665f1e34fbf590e9bb53eebea086fb28f4e0c31941bd5274e086dc9b5360b68c4976891b94c4e92ca01a languageName: node linkType: hard @@ -5088,10 +5125,10 @@ __metadata: linkType: hard "motion@npm:^12.4.1": - version: 12.23.12 - resolution: "motion@npm:12.23.12" + version: 12.23.24 + resolution: "motion@npm:12.23.24" dependencies: - framer-motion: "npm:^12.23.12" + framer-motion: "npm:^12.23.24" tslib: "npm:^2.4.0" peerDependencies: "@emotion/is-prop-valid": "*" @@ -5104,7 +5141,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 10/95670351c14d6925e891fac3d12719ed2e46000366abd38096870c46271071e3f22d0e9fa523809e614ee58aaeb1865fc19398dc8b408c2594512dc0eef392db + checksum: 10/d63d951676058001c6f234a6bdf8ed5a8fd222a38c1871ef209ed1fd87f2a288ec0e267fa616d80ac8837d0836a5f93ae85a80d773314517f19f304f25b81c3d languageName: node linkType: hard @@ -5148,20 +5185,20 @@ __metadata: linkType: hard "next-mdx-remote-client@npm:^2.1.2": - version: 2.1.3 - resolution: "next-mdx-remote-client@npm:2.1.3" + version: 2.1.7 + resolution: "next-mdx-remote-client@npm:2.1.7" dependencies: "@babel/code-frame": "npm:^7.27.1" - "@mdx-js/mdx": "npm:^3.1.0" - "@mdx-js/react": "npm:^3.1.0" - remark-mdx-remove-esm: "npm:^1.2.0" + "@mdx-js/mdx": "npm:^3.1.1" + "@mdx-js/react": "npm:^3.1.1" + remark-mdx-remove-esm: "npm:^1.2.1" serialize-error: "npm:^12.0.0" vfile: "npm:^6.0.3" vfile-matter: "npm:^5.0.1" peerDependencies: - react: ^19.1.0 - react-dom: ^19.1.0 - checksum: 10/3837c63edf7d707de2eea9b4c565eeb7e505a769e93c2673f746ec9993c644f7cd0aacb8bad911eff9ea63190f48c2c16ffe98d47c39591c5dac29c8bf9a9e0c + react: ^19.1 + react-dom: ^19.1 + checksum: 10/8aaf6c2f11b0ed398703165c35c0355d1f058521780191684e6fe7e45698effe50ba68b154bae9db84b13e82dff98f380224d588acca6e389aeb73062ecdd31d languageName: node linkType: hard @@ -5773,16 +5810,16 @@ __metadata: languageName: node linkType: hard -"remark-mdx-remove-esm@npm:^1.2.0": - version: 1.2.0 - resolution: "remark-mdx-remove-esm@npm:1.2.0" +"remark-mdx-remove-esm@npm:^1.2.1": + version: 1.2.1 + resolution: "remark-mdx-remove-esm@npm:1.2.1" dependencies: "@types/mdast": "npm:^4.0.4" mdast-util-mdxjs-esm: "npm:^2.0.1" unist-util-remove: "npm:^4.0.0" peerDependencies: unified: ^11 - checksum: 10/0a1155e08395ab73f877948455fc04d7457864f7556617efabecae7ea1b441cec2ca7ee9672e16a6cd56f2a16c57a4778f901e77d19052d1dd245de5bdf4618f + checksum: 10/092e95ca0649cfe08c47900d9922172b531e1d60b0f90955f51a7282620a1ae53a95dddde3f8d789cdd114a2d515a9372bc72b3e46200ff6f930bd89f0985982 languageName: node linkType: hard @@ -5821,10 +5858,10 @@ __metadata: languageName: node linkType: hard -"require-directory@npm:^2.1.1": - version: 2.1.1 - resolution: "require-directory@npm:2.1.1" - checksum: 10/a72468e2589270d91f06c7d36ec97a88db53ae5d6fe3787fadc943f0b0276b10347f89b363b2a82285f650bdcc135ad4a257c61bdd4d00d6df1fa24875b0ddaf +"reselect@npm:^5.1.1": + version: 5.1.1 + resolution: "reselect@npm:5.1.1" + checksum: 10/1fdae11a39ed9c8d85a24df19517c8372ee24fefea9cce3fae9eaad8e9cefbba5a3d4940c6fe31296b6addf76e035588c55798f7e6e147e1b7c0855f119e7fa5 languageName: node linkType: hard @@ -5928,15 +5965,6 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.8.1": - version: 7.8.2 - resolution: "rxjs@npm:7.8.2" - dependencies: - tslib: "npm:^2.1.0" - checksum: 10/03dff09191356b2b87d94fbc1e97c4e9eb3c09d4452399dddd451b09c2f1ba8d56925a40af114282d7bc0c6fe7514a2236ca09f903cf70e4bbf156650dddb49d - languageName: node - linkType: hard - "safe-array-concat@npm:^1.1.3": version: 1.1.3 resolution: "safe-array-concat@npm:1.1.3" @@ -6143,13 +6171,6 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:^1.8.1": - version: 1.8.3 - resolution: "shell-quote@npm:1.8.3" - checksum: 10/5473e354637c2bd698911224129c9a8961697486cff1fb221f234d71c153fc377674029b0223d1d3c953a68d451d79366abfe53d1a0b46ee1f28eb9ade928f4c - languageName: node - linkType: hard - "shiki@npm:^3.13.0": version: 3.13.0 resolution: "shiki@npm:3.13.0" @@ -6286,13 +6307,6 @@ __metadata: languageName: node linkType: hard -"spawn-command@npm:0.0.2": - version: 0.0.2 - resolution: "spawn-command@npm:0.0.2" - checksum: 10/f13e8c3c63abd4a0b52fb567eba5f7940d480c5ed3ec61781d38a1850f179b1196c39e6efa2bbd301f82c1bf1cd7807abc8fbd8fc8e44bcaa3975a124c0d1657 - languageName: node - linkType: hard - "ssri@npm:^12.0.0": version: 12.0.0 resolution: "ssri@npm:12.0.0" @@ -6337,7 +6351,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -6488,21 +6502,21 @@ __metadata: languageName: node linkType: hard -"style-to-js@npm:1.1.17, style-to-js@npm:^1.0.0": - version: 1.1.17 - resolution: "style-to-js@npm:1.1.17" +"style-to-js@npm:1.1.19, style-to-js@npm:^1.0.0": + version: 1.1.19 + resolution: "style-to-js@npm:1.1.19" dependencies: - style-to-object: "npm:1.0.9" - checksum: 10/431f2fca8a55a61939a83ff0f58638e2996621ad93a97cf93f2be5115f411330d4e506ccf18621bd45607ec161546b763bb6961ad08238ad939b6261ff377230 + style-to-object: "npm:1.0.12" + checksum: 10/c25f3a96368f258c90a886ec20b8a15ae035664e46eeea6c36f105fbc1e099ee81eaac355b7f5f948d8bb9d103c048a97b3d09e785c680ff2b4dd6d77cb76a95 languageName: node linkType: hard -"style-to-object@npm:1.0.9": - version: 1.0.9 - resolution: "style-to-object@npm:1.0.9" +"style-to-object@npm:1.0.12": + version: 1.0.12 + resolution: "style-to-object@npm:1.0.12" dependencies: - inline-style-parser: "npm:0.2.4" - checksum: 10/fd0c131a83103fe4025afd8e0fd90c605054d485ad80f2ab402e7afa79f482f4b05fff40b6aa661cb1b835e5c56bb0644dc38cbf9b3d2982fc552435db3dae50 + inline-style-parser: "npm:0.2.6" + checksum: 10/97b91c2056f4fedb573224accba080aaa96b48a7b120a007b83415c9b18b727d0d6588b9168a1b85da06dd1abacc328f6dd774e907721901e40503a2e7a78c89 languageName: node linkType: hard @@ -6531,15 +6545,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.1.1": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: "npm:^4.0.0" - checksum: 10/157b534df88e39c5518c5e78c35580c1eca848d7dbaf31bbe06cdfc048e22c7ff1a9d046ae17b25691128f631a51d9ec373c1b740c12ae4f0de6e292037e4282 - languageName: node - linkType: hard - "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" @@ -6547,6 +6552,13 @@ __metadata: languageName: node linkType: hard +"tabbable@npm:^6.2.0": + version: 6.3.0 + resolution: "tabbable@npm:6.3.0" + checksum: 10/3e54a0b770d26bc20c3de5837652be19f5efa8bfa869f580af24bcf60de934506e9401a577213186b5e86ebcf6b5290a5429d354cc3041471815f5095e44e51a + languageName: node + linkType: hard + "tar@npm:^7.4.3": version: 7.4.3 resolution: "tar@npm:7.4.3" @@ -6594,15 +6606,6 @@ __metadata: languageName: node linkType: hard -"tree-kill@npm:^1.2.2": - version: 1.2.2 - resolution: "tree-kill@npm:1.2.2" - bin: - tree-kill: cli.js - checksum: 10/49117f5f410d19c84b0464d29afb9642c863bc5ba40fcb9a245d474c6d5cc64d1b177a6e6713129eb346b40aebb9d4631d967517f9fbe8251c35b21b13cd96c7 - languageName: node - linkType: hard - "trim-lines@npm:^3.0.0": version: 3.0.1 resolution: "trim-lines@npm:3.0.1" @@ -6638,7 +6641,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.8.0": +"tslib@npm:^2.0.1, tslib@npm:^2.4.0, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10/3e2e043d5c2316461cb54e5c7fe02c30ef6dccb3384717ca22ae5c6b5bc95232a6241df19c622d9c73b809bea33b187f6dbc73030963e29950c2141bc32a79f7 @@ -6722,22 +6725,22 @@ __metadata: linkType: hard "typescript@npm:^5": - version: 5.9.2 - resolution: "typescript@npm:5.9.2" + version: 5.9.3 + resolution: "typescript@npm:5.9.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/cc2fe6c822819de5d453fa25aa9f32096bf70dde215d481faa1ad84a283dfb264e33988ed8f6d36bc803dd0b16dbe943efa311a798ef76d5b3892a05dfbfd628 + checksum: 10/c089d9d3da2729fd4ac517f9b0e0485914c4b3c26f80dc0cffcb5de1719a17951e92425d55db59515c1a7ddab65808466debb864d0d56dcf43f27007d0709594 languageName: node linkType: hard "typescript@patch:typescript@npm%3A^5#optional!builtin": - version: 5.9.2 - resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5" + version: 5.9.3 + resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/bd810ab13e8e557225a8b5122370385440b933e4e077d5c7641a8afd207fdc8be9c346e3c678adba934b64e0e70b0acf5eef9493ea05170a48ce22bef845fdc7 + checksum: 10/696e1b017bc2635f4e0c94eb4435357701008e2f272f553d06e35b494b8ddc60aa221145e286c28ace0c89ee32827a28c2040e3a69bdc108b1a5dc8fb40b72e3 languageName: node linkType: hard @@ -6937,6 +6940,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:^1.5.0": + version: 1.6.0 + resolution: "use-sync-external-store@npm:1.6.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10/b40ad2847ba220695bff2d4ba4f4d60391c0fb4fb012faa7a4c18eb38b69181936f5edc55a522c4d20a788d1a879b73c3810952c9d0fd128d01cb3f22042c09e + languageName: node + linkType: hard + "util@npm:^0.12.5": version: 0.12.5 resolution: "util@npm:0.12.5" @@ -7077,7 +7089,7 @@ __metadata: languageName: node linkType: hard -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" dependencies: @@ -7121,13 +7133,6 @@ __metadata: languageName: node linkType: hard -"y18n@npm:^5.0.5": - version: 5.0.8 - resolution: "y18n@npm:5.0.8" - checksum: 10/5f1b5f95e3775de4514edbb142398a2c37849ccfaf04a015be5d75521e9629d3be29bd4432d23c57f37e5b61ade592fb0197022e9993f81a06a5afbdcda9346d - languageName: node - linkType: hard - "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0" @@ -7151,28 +7156,6 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^21.1.1": - version: 21.1.1 - resolution: "yargs-parser@npm:21.1.1" - checksum: 10/9dc2c217ea3bf8d858041252d43e074f7166b53f3d010a8c711275e09cd3d62a002969a39858b92bbda2a6a63a585c7127014534a560b9c69ed2d923d113406e - languageName: node - linkType: hard - -"yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" - dependencies: - cliui: "npm:^8.0.1" - escalade: "npm:^3.1.1" - get-caller-file: "npm:^2.0.5" - require-directory: "npm:^2.1.1" - string-width: "npm:^4.2.3" - y18n: "npm:^5.0.5" - yargs-parser: "npm:^21.1.1" - checksum: 10/abb3e37678d6e38ea85485ed86ebe0d1e3464c640d7d9069805ea0da12f69d5a32df8e5625e370f9c96dd1c2dc088ab2d0a4dd32af18222ef3c4224a19471576 - languageName: node - linkType: hard - "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" diff --git a/docs/auth/oidc.md b/docs/auth/oidc.md index 250736cec7..7c4b09d9bf 100644 --- a/docs/auth/oidc.md +++ b/docs/auth/oidc.md @@ -1,7 +1,7 @@ --- id: oidc title: OIDC provider from scratch -description: This section shows how to use an OIDC provider from scratch, same steps apply for custom providers. +description: This section shows how to enable and use the Backstage OIDC provider. --- :::info @@ -11,78 +11,65 @@ system, you may want to read [its own article](https://github.com/backstage/back instead, and [consider migrating](../backend-system/building-backends/08-migrating.md)! ::: -This section shows how to use an OIDC provider from scratch, same steps apply for custom -providers. Please note these steps are for using a provider, not how to implement one, -and Backstage recommends creating custom providers specific to the IDP, so we'll use a -`azureOIDC` provider throughout this example, feel free to change any of those refs -to your provider name. +This section shows how to enable and use the Backstage OIDC provider. ## Summary -To add providers not enabled by default like OIDC, we need to follow some steps, we -assume you already have a sign-in page to which we'll add the provider so users can -sign in through the provider. In simple steps here's how you enable the provider: +OIDC is a protocol which has numerous implementations. It's likely that many of your users won't know what the OIDC **protocol** is, but they will recognise your OIDC **implementation**. Backstage supplies a generic `oidc` authorization strategy. You should re-badge this with the name and branding of your OIDC implementation, so that your users will recognise it on the Backstage sign-in page. + +For example, if your organization uses [Keycloak](https://www.keycloak.org), you would re-badge the OIDC provider as `Keycloak` and tell users to `Sign In using Keycloak`. + +## Steps + +The Backstage OIDC provider is not enabled by default. You need to manually enable the provider, and tell it which OIDC server you want to use. + +To enable the Backstage OIDC provider: - Create an API reference to identify the provider. - Create the API factory that will handle the authentication. - Add or reuse an auth provider so you can authenticate. - Add or reuse a resolver to handle the result from the authentication. - Configure the provider to access your 3rd party auth solution. -- Add the provider to sign in page so users can login with it. +- Add the provider to the Backstage sign-in page. + +For simplicity, we assume that you only have a single OIDC provider in your Backstage installation. (If you need to have multiple OIDC providers in Backstage, the steps will be different.) We'll explain each step more in detail next. -### The API reference +### The API Reference -An API reference exist for the sake of **Dependency Injection**, check [Utility APIs][4] -for extended explanation. +An API reference exists to enable **Dependency Injection**. (See [Utility APIs][4] for an extended explanation.) -In this OIDC example, we'll create the API reference directly in the -`packages/app/src/apis.ts` file, it is not a requirement to put the reference in this -file. Any location will do as long as it's available to be imported to where the API -factory is, as well as easily accessible to the rest of the application so any package -and plugin can inject the API instance when necessary. - -An example of such would be when you use an auth provider from a library installed with -NPM, or any other library repository, you would import the API ref from the library. +In this example, we'll create the API ref directly in the `packages/app/src/apis.ts` file. It is not a requirement to put the ref in this file. Any location will do as long as it's available to be imported to where the API factory is, as well as easily accessible to the rest of the application so any package and plugin can inject the API instance when necessary. ```ts -export const azureOIDCAuthApiRef: ApiRef< +export const keycloakAuthApiRef: ApiRef< OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi > = createApiRef({ - id: 'auth.my-custom-provider', + id: 'auth.keycloak', }); ``` -Please note a few things, the ID can be anything you want as long as it doesn't conflict -with other refs, backstage recommends to use a custom name that references your custom -provider, for example we are using OIDC protocol with Azure, so we could use something -like `auth.azure.oidc` as well. +The `id` of the API ref can be anything you want, as long as it doesn't conflict with other refs. Backstage recommends to use a custom name that references your custom provider. -Also we're exporting this reference, as well as the `typings`, we need to -be able to import this reference anywhere in the app, and the `typings` will tell typescript +:::note TypeScript Note +As we're exporting this API reference, as well as the TypeScript types, we need to +be able to import this reference anywhere in the app. The types will tell TypeScript what instance we're getting from DI when injecting the API. In this case we are defining an API for authentication, so we tell TS that this instance complies with 4 API interfaces: -- The OICD API that will handle authentication. +- The OIDC API that will handle authentication. - Profile API for requesting user profile info from the auth provider in question. - Backstage identity API to handle and associate the user profile with backstage identity. -- Session API, to handle the session the user will have while logged in. +- Session API, to handle the session the user will have while signed in. + ::: -### The API Factory +### The API Factory (and auth provider) -A factory is a function that can take some parameters or dependencies and return an -instance of something, in our case it will be a function that requests some backstage -APIs and use them to create an instance of an OIDC API provider. +The Backstage API factories are part of the Backstage Dependency Injection system. The factory function runs once, when something in your Backstage app first attempts to use an instance of the API it provides. The instance is then cached by the DI system for subsequent lookups. -Please note that this function only runs (creates the instance) when somewhere else in -the app you request the DI to give you an instance of the OIDC provider using the API ref -defined above, and the DI will only run this function the first time, from then on any -other DI injection will just receive the same instance created the first time, basically -the instance is cached by the DI library, a singleton. - -Let's add our OIDC API factory to the APIs array in the `packages/app/src/apis.ts` file: +Let's add a new API factory to the `apis` array in the `packages/app/src/apis.ts` file. We will tell it to use the OIDC auth provider internally. ```ts title="packages/app/src/apis.ts" /* highlight-add-next-line */ @@ -91,26 +78,29 @@ import { OAuth2 } from '@backstage/core-app-api'; export const apis: AnyApiFactory[] = [ /* highlight-add-start */ createApiFactory({ - api: azureOIDCAuthApiRef, + api: keycloakAuthApiRef, deps: { discoveryApi: discoveryApiRef, oauthRequestApi: oauthRequestApiRef, configApi: configApiRef, }, factory: ({ discoveryApi, oauthRequestApi, configApi }) => + // delegate auth to the OAuth2 strategy OAuth2.create({ configApi, discoveryApi, oauthRequestApi, provider: { - id: 'my-auth-provider', - title: 'My custom auth provider', + // this value MUST be 'oidc' + // it maps our Keycloak-branded sign-in provider onto Backstage's generic OIDC auth strategy + id: 'oidc', + title: 'Keycloak', icon: () => null, }, environment: configApi.getOptionalString('auth.environment'), defaultScopes: ['openid', 'profile', 'email'], popupOptions: { - // optional, used to customize login in popup size + // optional, used to customize sign-in window size size: { fullscreen: true, }, @@ -125,27 +115,14 @@ export const apis: AnyApiFactory[] = [ }), }), /* highlight-add-end */ - // .. ]; ``` -Please note we're importing the `OAuth2` class from `@backstage/core-app-api` effectively -delegating the authentication to it. Also we're using the `my-auth-provider` ID to tell -`OAuth2` to use the auth provider we'll define in the next section, and added the default -scopes to request ID, profile, email and user read permissions. - -## The Auth Provider - -The Auth Provider is responsible for authenticating with the 3rd party service, and give -us back the credentials, here's where you pick which protocol to use, be it Auth0, OAuth2, -OIDC, SAML or any other that your 3rd party IDP provider supports. - ### The Resolver -Resolvers exist to map user identity from the 3rd party (in this case an azure IDP -provider) to the backstage user identity. +Resolvers exist to map the user identity from the 3rd party (in this case Keycloak) to the Backstage user identity. -The default OIDC provider has built-in resolvers, here is how you configure them: +The default OIDC provider has a choice of built-in resolvers, here is how you configure them: ```yaml title="app-config.yaml" auth: @@ -159,7 +136,7 @@ auth: - resolver: emailMatchingUserEntityProfileEmail ``` -But you can also write a custom resolver as well, see an example below: +If none of the built-in resolvers are suitable, you can alternatively write a custom resolver. See an example below: ```ts title="in packages/backend/src/index.ts" /* highlight-add-start */ @@ -174,15 +151,15 @@ const myAuthProviderModule = createBackendModule({ // This ID must be exactly "auth" because that's the plugin it targets pluginId: 'auth', // This ID must be unique, but can be anything - moduleId: 'my-auth-provider', + moduleId: 'keycloak-auth-provider', register(reg) { reg.registerInit({ deps: { providers: authProvidersExtensionPoint }, async init({ providers }) { providers.registerProvider({ // This ID must match the actual provider config, e.g. addressing - // auth.providers.azure means that this must be "azure". - providerId: 'my-auth-provider', + // auth.providers.keycloak means that this must be "keycloak". + providerId: 'keycloak', // Use createProxyAuthProviderFactory instead if it's one of the proxy // based providers rather than an OAuth based one factory: createOAuthProviderFactory({ @@ -215,76 +192,85 @@ backend.add(myAuthProviderModule); //... ``` -For a more a detailed explanation about resolvers check the -[Identity Resolver][1] page. +For a more detailed explanation about resolvers check the [Identity Resolver][1] page. -### The configuration +### The Configuration -Since we are using our custom OIDC Auth Provider, we need to add a configuration based -on the provider used, in this case based on OIDC protocol (remember the 3rd party has to -support the protocol). +We will now configure our Keycloak-branded OIDC Auth Provider in Backstage, so that it can talk to our Keycloak server. -In this example we'll configure OIDC with `my-auth-provider`, to do so we need to -[Create app registration][2] in the Azure console, the only difference is that the -`http://localhost:7007/api/auth/microsoft/handler/frame` URL needs to change to -`http://localhost:7007/api/auth/my-auth-provider/handler/frame`. +The first step is to register an OIDC client app for Backstage in your Keycloak server. -Then we need to configure the env variables for the provider, based on the provider's code -in `plugins/auth-backend/src/providers/oidc/provider.ts` we need the following variables -in the `app-config.yaml`: +Then we need to configure the provider. Based on the provider's code in `plugins/auth-backend/src/providers/oidc/provider.ts` we need the following parameters in the `app-config.yaml`: ```yaml title="app-config.yaml" auth: environment: development - ### Providing an auth.session.secret will enable session support in the auth-backend session: - secret: ${SESSION_SECRET} + secret: ${AUTH_SESSION_SECRET} providers: - my-auth-provider: + oidc: development: metadataUrl: https://example.com/.well-known/openid-configuration - clientId: ${AUTH_MY_CLIENT_ID} - clientSecret: ${AUTH_MY_CLIENT_SECRET} + clientId: ${AUTH_OIDC_CLIENT_ID} + clientSecret: ${AUTH_OIDC_CLIENT_SECRET} ``` -Anything enclosed in `${}` can be replaced directly in the yaml, or provided as -environment variables, the way you obtain all these except `scope` and `prompt` is to -check the App Registration you created: +Anything enclosed in `${}` can be replaced directly in the YAML, or provided as environment variables. + +#### Required Parameters + +These parameters must always be set. - `clientId`: Grab from the Overview page. - `clientSecret`: Can only be seen when creating the secret, if you lose it you'll need a new secret. - `metadataUrl`: In Overview > Endpoints tab, grab OpenID Connect metadata document URL. + +The OIDC provider **also** requires the `auth.session.secret` to be set. + +#### Optional Parameters + +These parameters have implicit default values. Don't override them unless you know what you're doing. + - `authorizationUrl` and `tokenUrl`: Open the `metadataUrl` in a browser, that json will hold these 2 urls somewhere in there. -- `tokenEndpointAuthMethod`: Don't define it, use the default unless you know what it does. -- `tokenSignedResponseAlg`: Don't define it, use the default unless you know what it does. +- `tokenEndpointAuthMethod` +- `tokenSignedResponseAlg` - `scope`: Only used if we didn't specify `defaultScopes` in the provider's factory, basically the same thing. -- `prompt`: Recommended to use `auto` so the browser will request login to the IDP if the +- `prompt`: Recommended to use `auto` so the browser will request sign-in to the IDP if the user has no active session. -- `sessionDuration` (optional): Lifespan of the user session. +- `sessionDuration`: Lifespan of the user session. -Note that for the time being, any change in this yaml file requires a restart of the app, -also you need to have the `session.secret` part to use OIDC (some other providers might -need this as well) to support user sessions. +:::note Config Reloading +Backstage does not yet support hot reloading of auth provider configuration. Any changes to this YAML file require a restart of Backstage. +::: -### The Sign In provider +### The Sign-In Page -The last step is to add the provider to the `SignInPage` so users can sign in with your -new provider, please follow the [Sign In Configuration][3] docs, here's where you import -and use the API reference we defined earlier. +The last step is to add the provider to the sign-in page, so users can sign in with your new provider. + +If you are using the standard Backstage [`SignInPage`][3] component, you can just add it to the `providers` array like this: + +```ts title="in packages/app/src/identityProviders.ts" +export const providers = [ + // other providers... + { + id: 'keycloak-auth-provider', + title: 'Keycloak', + message: 'Sign In using Keycloak', + apiRef: keycloakAuthApiRef, + }, +]; +``` :::note Note - -These steps apply to most if not all the providers, including custom providers, the main -difference between different providers will be the contents of the API factory, the code +These steps apply to most auth providers. The main +difference between providers will be the contents of the API factory, the code in the Auth Provider Factory, the resolver, and the different variables each provider needs in the YAML config or env variables. - ::: [1]: https://backstage.io/docs/auth/identity-resolver -[2]: https://backstage.io/docs/auth/microsoft/provider#create-an-app-registration-on-azure [3]: https://backstage.io/docs/auth/#sign-in-configuration [4]: https://backstage.io/docs/api/utility-apis diff --git a/docs/backend-system/core-services/root-instance-metadata.md b/docs/backend-system/core-services/root-instance-metadata.md new file mode 100644 index 0000000000..109042f1a5 --- /dev/null +++ b/docs/backend-system/core-services/root-instance-metadata.md @@ -0,0 +1,44 @@ +--- +id: root-instance-metadata +title: Root Instance Metadata Service +sidebar_label: Root Instance Metadata +description: Documentation for the Root Instance Metadata service +--- + +The root instance metadata service provides information about the running Backstage backend instance. Currently, it provides a list of all installed backend plugins. + +:::note Note + +The root instance metadata service only provides information about the specific Backstage instance you're running on. In more complex deployments with multiple Backstage instances, this service will not provide a complete list of all plugins across all instances. + +::: + +## Using the service + +The following example shows how to use the root instance metadata service in your `example` backend plugin to access the list of installed backend plugins. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + instanceMetadata: coreServices.rootInstanceMetadata, + }, + async init({ instanceMetadata }) { + const plugins = instanceMetadata.getInstalledPlugins(); + console.log('Installed plugins:', plugins); + }, + }); + }, +}); +``` + +## Dynamic plugin registration + +The root instance metadata service picks up plugins that are registered at start time through a `backend.start()` call. You need to restart the running backend instance to pick up newly installed plugins. diff --git a/docs/frontend-system/architecture/20-extensions.md b/docs/frontend-system/architecture/20-extensions.md index 24a5f24e12..a6d00a3131 100644 --- a/docs/frontend-system/architecture/20-extensions.md +++ b/docs/frontend-system/architecture/20-extensions.md @@ -352,3 +352,69 @@ const extension = createExtension({ }, }); ``` + +## Relative attachment points + +When creating an extension or an [extension blueprint](./23-extension-blueprints.md) you can specify an attachment point that is relative to the current plugin. This is particularly useful for groups of blueprints that are part of a common hierarchy, with extensions from one blueprint attaching to extensions from the other blueprint. For example, the following pair of extension definitions could be installed multiple times in different plugins, each creating their own hierarchy: + +```tsx +// Parent extension with a fixed attachment point +const parentExtension = createExtension({ + kind: 'section', + attachTo: [{ id: 'app/some-fixed-extension', input: 'children' }], + inputs: { + content: createExtensionInput([coreExtensionData.reactElement], { + singleton: true, + }), + }, + output: [coreExtensionData.reactElement], + factory({ inputs }) { + return [ + coreExtensionData.reactElement( +
+

Section Title

+ {inputs.content.get(coreExtensionData.reactElement)} +
, + ), + ]; + }, +}); + +// Child extension with a relative attachment point +const childExtension = createExtension({ + kind: 'section-content', + attachTo: [{ relative: { kind: 'section' }, input: 'content' }], + output: [coreExtensionData.reactElement], + factory() { + return [coreExtensionData.reactElement(

Section Content

)]; + }, +}); +``` + +## Extension input references + +Building on the relative attachment point concept, you can also reference extension inputs directly via the `inputs` property of an extension definition. This provides a more convenient and type-safe way to attach child extensions, especially when using blueprints that provide a nested hierarchy of extensions. + +Extension inputs references are always relative, this means that they can only be used for referencing extensions within the same plugin. + +Each extension definition exposes an `inputs` property that contains references to all of its defined inputs. These references can be passed directly to the `attachTo` option when creating child extensions: + +```tsx +const parent = createExtension({ + inputs: { + children: createExtensionInput([coreExtensionData.reactElement]), + }, + // other options... +}); + +// Create a child extension that attaches to the parent's input +const child = createExtension({ + attachTo: page.inputs.children, // Direct reference to the input + output: [coreExtensionData.reactElement], // Outputs are verified against the parent input + // other options... +}); +``` + +These references are a type-safe way to attach child extensions, it both ensures that the parent input is present, as well as the child providing the required data for the parent. + +Under the hood, input references are resolved in the same way as relative attachment points, using the extension's kind, namespace, and name to construct the final attachment target. diff --git a/docs/golden-path/create-app/customize-theme.md b/docs/golden-path/create-app/customize-theme.md new file mode 100644 index 0000000000..a79507de59 --- /dev/null +++ b/docs/golden-path/create-app/customize-theme.md @@ -0,0 +1,613 @@ +--- +id: custom-theme +title: 005 - Customize your App's theme +description: Documentation on customizing the look and feel of your Backstage app. +--- + +Backstage ships with a default theme with a light and dark mode variant. The themes are provided as a part of the [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme) package, which also includes utilities for customizing the default theme, or creating completely new themes. + +## Creating a Custom Theme + +The easiest way to create a new theme is to use the `createUnifiedTheme` function exported by the [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme) package. You can use it to override some basic parameters of the default theme such as the color palette and font. + +For example, you can create a new theme based on the default light theme like this: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + }), + fontFamily: 'Comic Sans MS', + defaultPageTheme: 'home', +}); +``` + +:::note Note + +we recommend creating a `theme` folder in `packages/app/src` to place your theme file to keep things nicely organized. + +::: + +You can also create a theme from scratch that matches the `BackstageTheme` type exported by [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). See the +[Material UI docs on theming](https://material-ui.com/customization/theming/) for more information about how that can be done. + +## Using your Custom Theme + +To add a custom theme to your Backstage app, you pass it as configuration to `createApp`. + +For example, adding the theme that we created in the previous section can be done like this: + +```tsx title="packages/app/src/App.tsx" +import { createApp } from '@backstage/app-defaults'; +import { ThemeProvider } from '@material-ui/core/styles'; +import CssBaseline from '@material-ui/core/CssBaseline'; +import LightIcon from '@material-ui/icons/WbSunny'; +import { UnifiedThemeProvider} from '@backstage/theme'; +import { myTheme } from './themes/myTheme'; + +const app = createApp({ + apis: ..., + plugins: ..., + themes: [{ + id: 'my-theme', + title: 'My Custom Theme', + variant: 'light', + icon: , + Provider: ({ children }) => ( + + ), + }] +}) +``` + +Note that your list of custom themes overrides the default themes. If you still want to use the default themes, they are exported as `themes.light` and `themes.dark` from [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). + +## Example of a custom theme + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + genPageTheme, + palettes, + shapes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: { + ...palettes.light, + primary: { + main: '#343b58', + }, + secondary: { + main: '#565a6e', + }, + error: { + main: '#8c4351', + }, + warning: { + main: '#8f5e15', + }, + info: { + main: '#34548a', + }, + success: { + main: '#485e30', + }, + background: { + default: '#d5d6db', + paper: '#d5d6db', + }, + banner: { + info: '#34548a', + error: '#8c4351', + text: '#343b58', + link: '#565a6e', + }, + errorBackground: '#8c4351', + warningBackground: '#8f5e15', + infoBackground: '#343b58', + navigation: { + background: '#343b58', + indicator: '#8f5e15', + color: '#d5d6db', + selectedColor: '#ffffff', + }, + }, + }), + defaultPageTheme: 'home', + fontFamily: 'Comic Sans MS', + /* below drives the header colors */ + pageTheme: { + home: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + documentation: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave2, + }), + tool: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.round }), + service: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + website: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + library: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + other: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + app: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + apis: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + }, +}); +``` + +For a more complete example of a custom theme including Backstage and Material UI component overrides, see the [Aperture theme](https://github.com/backstage/demo/blob/master/packages/app/src/theme/aperture.ts) from the [Backstage demo site](https://demo.backstage.io). + +## Custom Typography + +When creating a custom theme you can also customize various aspects of the default typography, here's an example using simplified theme: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + htmlFontSize: 16, + fontFamily: 'Arial, sans-serif', + h1: { + fontSize: 54, + fontWeight: 700, + marginBottom: 10, + }, + h2: { + fontSize: 40, + fontWeight: 700, + marginBottom: 8, + }, + h3: { + fontSize: 32, + fontWeight: 700, + marginBottom: 6, + }, + h4: { + fontWeight: 700, + fontSize: 28, + marginBottom: 6, + }, + h5: { + fontWeight: 700, + fontSize: 24, + marginBottom: 4, + }, + h6: { + fontWeight: 700, + fontSize: 20, + marginBottom: 2, + }, + }, + defaultPageTheme: 'home', + }), +}); +``` + +If you wanted to only override a sub-set of the typography setting, for example just `h1` then you would do this: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + defaultTypography, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + ...defaultTypography, + htmlFontSize: 16, + fontFamily: 'Roboto, sans-serif', + h1: { + fontSize: 72, + fontWeight: 700, + marginBottom: 10, + }, + }, + defaultPageTheme: 'home', + }), +}); +``` + +## Custom Fonts + +To add custom fonts, you first need to store the font so that it can be imported. We suggest creating the `assets/fonts` directory in your front-end application `src` folder. + +You can then declare the font style following the `@font-face` syntax from [Material UI Typography](https://mui.com/material-ui/customization/typography/). + +After that you can then utilize the `styleOverrides` of `MuiCssBaseline` under components to add a font to the `@font-face` array. + +```ts title="packages/app/src/theme/myTheme.ts" +import MyCustomFont from '../assets/fonts/My-Custom-Font.woff2'; + +const myCustomFont = { + fontFamily: 'My-Custom-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Custom-Font'), + url(${MyCustomFont}) format('woff2'), + `, +}; + +export const myTheme = createUnifiedTheme({ + fontFamily: 'My-Custom-Font', + palette: palettes.light, + components: { + MuiCssBaseline: { + styleOverrides: { + '@font-face': [myCustomFont], + }, + }, + }, +}); +``` + +If you want to utilize different or multiple fonts, then you can set the top level `fontFamily` to what you want for your body, and then override `fontFamily` in `typography` to control fonts for various headings. + +```ts title="packages/app/src/theme/myTheme.ts" +import MyCustomFont from '../assets/fonts/My-Custom-Font.woff2'; +import myAwesomeFont from '../assets/fonts/My-Awesome-Font.woff2'; + +const myCustomFont = { + fontFamily: 'My-Custom-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Custom-Font'), + url(${MyCustomFont}) format('woff2'), + `, +}; + +const myAwesomeFont = { + fontFamily: 'My-Awesome-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Awesome-Font'), + url(${myAwesomeFont}) format('woff2'), + `, +}; + +export const myTheme = createUnifiedTheme({ + fontFamily: 'My-Custom-Font', + components: { + MuiCssBaseline: { + styleOverrides: { + '@font-face': [myCustomFont, myAwesomeFont], + }, + }, + }, + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + ...defaultTypography, + htmlFontSize: 16, + fontFamily: 'My-Custom-Font', + h1: { + fontSize: 72, + fontWeight: 700, + marginBottom: 10, + fontFamily: 'My-Awesome-Font', + }, + }, + defaultPageTheme: 'home', + }), +}); +``` + +## Overriding Backstage and Material UI components styles + +When creating a custom theme you would be applying different values to component's CSS rules that use the theme object. For example, a Backstage component's styles might look like this: + +```tsx +const useStyles = makeStyles( + theme => ({ + header: { + padding: theme.spacing(3), + boxShadow: '0 0 8px 3px rgba(20, 20, 20, 0.3)', + backgroundImage: theme.page.backgroundImage, + }, + }), + { name: 'BackstageHeader' }, +); +``` + +Notice how the `padding` is getting its value from `theme.spacing`, that means that setting a value for spacing in your custom theme would affect this component padding property and the same goes for `backgroundImage` which uses `theme.page.backgroundImage`. However, the `boxShadow` property doesn't reference any value from the theme, that means that creating a custom theme wouldn't be enough to alter the `box-shadow` property or to add css rules that aren't already defined like a margin. For these cases you should also create an override. + +Here's how you would do that: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + }), + fontFamily: 'Comic Sans MS', + defaultPageTheme: 'home', + components: { + BackstageHeader: { + styleOverrides: { + header: ({ theme }) => ({ + width: 'auto', + margin: '20px', + boxShadow: 'none', + borderBottom: `4px solid ${theme.palette.primary.main}`, + }), + }, + }, + }, +}); +``` + +## Custom Logo + +In addition to a custom theme, you can also customize the logo displayed at the far top left of the site. + +In your frontend app, locate `src/components/Root/` folder. You'll find two components: + +- `LogoFull.tsx` - A larger logo used when the Sidebar navigation is opened. +- `LogoIcon.tsx` - A smaller logo used when the Sidebar navigation is closed. + +To replace the images, you can simply replace the relevant code in those components with raw SVG definitions. + +You can also use another web image format such as PNG by importing it. To do this, place your new image into a new subdirectory such as `src/components/Root/logo/my-company-logo.png`, and then add this code: + +```tsx +import MyCustomLogoFull from './logo/my-company-logo.png'; + +const LogoFull = () => { + return ; +}; +``` + +## Icons + +So far you've seen how to create your own theme and add your own logo, in the following sections you'll be shown how to override the existing icons and how to add more icons + +### Custom Icons + +You can also customize the Project's _default_ icons. + +You can change the following [icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx). + +#### Requirements + +- Files in `.svg` format +- React components created for the icons + +#### Create React Component + +In your front-end application, locate the `src` folder. We suggest creating the `assets/icons` directory and `CustomIcons.tsx` file. + +```tsx title="customIcons.tsx" +import { SvgIcon, SvgIconProps } from '@material-ui/core'; + +export const ExampleIcon = (props: SvgIconProps) => ( + + + +); +``` + +#### Using the custom icon + +Supply your custom icon in `packages/app/src/App.tsx` + +```tsx title="packages/app/src/App.tsx" +/* highlight-add-next-line */ +import { ExampleIcon } from './assets/customIcons' + + +const app = createApp({ + apis, + components: { + {/* ... */} + }, + themes: [ + {/* ... */} + ], + /* highlight-add-start */ + icons: { + github: ExampleIcon, + }, + /* highlight-add-end */ + bindRoutes({ bind }) { + {/* ... */} + } +}) +``` + +### Adding Icons + +You can add more icons, if the [default icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx) do not fit your needs, so that they can be used in other places like for Links in your entities. For this example we'll be using icons from[Material UI](https://v4.mui.com/components/material-icons/) and specifically the `AlarmIcon`. Here's how to do that: + +1. First you will want to open your `App.tsx` in `/packages/app/src` +2. Then you want to import your icon, add this to the rest of your imports: `import AlarmIcon from '@material-ui/icons/Alarm';` +3. Next you want to add the icon like this to your `createApp`: + + ```tsx title="packages/app/src/App.tsx" + const app = createApp({ + apis: ..., + plugins: ..., + /* highlight-add-start */ + icons: { + alert: AlarmIcon, + }, + /* highlight-add-end */ + themes: ..., + components: ..., + }); + ``` + +4. Now we can reference `alert` for our icon in our entity links like this: + + ```yaml + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: artist-lookup + description: Artist Lookup + links: + - url: https://example.com/alert + title: Alerts + icon: alert + ``` + + And this is the result: + + ![Example Link with Alert icon](../../assets/getting-started/add-icons-links-example.png) + + Another way you can use these icons is from the `AppContext` like this: + + ```ts + import { useApp } from '@backstage/core-plugin-api'; + + const app = useApp(); + const alertIcon = app.getSystemIcon('alert'); + ``` + + You might want to use this method if you have an icon you want to use in several locations. + +:::note Note + +If the icon is not available as one of the default icons or one you've added then it will fall back to Material UI's `LanguageIcon` + +::: + +## Custom Sidebar + +As you've seen there are many ways that you can customize your Backstage app. The following section will show you how you can customize the sidebar. + +### Sidebar Sub-menu + +For this example we'll show you how you can expand the sidebar with a sub-menu: + +1. Open the `Root.tsx` file located in `packages/app/src/components/Root` as this is where the sidebar code lives +2. Then we want to add the following import for `useApp`: + + ```tsx title="packages/app/src/components/Root/Root.tsx" + import { useApp } from '@backstage/core-plugin-api'; + ``` + +3. Then update the `@backstage/core-components` import like this: + + ```tsx title="packages/app/src/components/Root/Root.tsx" + import { + Sidebar, + sidebarConfig, + SidebarDivider, + SidebarGroup, + SidebarItem, + SidebarPage, + SidebarScrollWrapper, + SidebarSpace, + useSidebarOpenState, + Link, + /* highlight-add-start */ + GroupIcon, + SidebarSubmenu, + SidebarSubmenuItem, + /* highlight-add-end */ + } from '@backstage/core-components'; + ``` + +4. Finally replace `` with this: + + ```tsx title="packages/app/src/components/Root/Root.tsx" + + + + + + + + + + + + + + ``` + +When you startup your Backstage app and hover over the Home option on the sidebar you'll now see a nice sub-menu appear with links to the various Kinds in your Catalog. It would look like this: + +![Sidebar sub-menu example](../../assets/getting-started/sidebar-submenu-example.png) + +You can see more ways to use this in the [Storybook Sidebar examples](https://backstage.io/storybook/?path=/story/layout-sidebar--sample-scalable-sidebar) + +## Custom Homepage + +In addition to a custom theme, a custom logo, you can also customize the +homepage of your app. Read the full guide on the [next page](../../getting-started/homepage.md). + +## Migrating to Material UI v5 + +We now support Material UI v5 in Backstage. Check out our [migration guide](../../tutorials/migrate-to-mui5.md) to get started. diff --git a/docs/golden-path/create-app/index.md b/docs/golden-path/create-app/index.md new file mode 100644 index 0000000000..ebd736594d --- /dev/null +++ b/docs/golden-path/create-app/index.md @@ -0,0 +1,16 @@ +--- +id: index +title: 'Creating your first Backstage app' +--- + +### Prerequisites + +None! + +### What should I get out of this guide? + +This guide is the first of 4 Golden Paths that will walk you through everything you need to start working with Backstage. We'll touch on how to get started and spin up a new app, how to write plugins, how to deploy your app to production and how to drive adoption for your new portal. Even if you're non-technical, you can skip forward to the `adoption` Golden Path and learn about how to help your team's new developer portal succeed. + +### Structure + +As mentioned above, this is the first of 4 Golden Paths - you should make sure this guide is 100% complete before continuing on to the other Golden Paths (`adoption` is the exception). We'll start by spinning up a new app for you, walking through what we just created and what you can do after you have a working app. diff --git a/docs/golden-path/create-app/installing-plugins.md b/docs/golden-path/create-app/installing-plugins.md new file mode 100644 index 0000000000..ab1e1a68c5 --- /dev/null +++ b/docs/golden-path/create-app/installing-plugins.md @@ -0,0 +1,69 @@ +--- +id: installing-plugins +sidebar_label: 003 - Installing plugins +title: 003 - Installing plugins +--- + +Now that you have a working Backstage app, let's walk through the most valuable part of the Backstage ecosystem - plugins! + +## What is a Backstage plugin? + +A Backstage plugin usually consists of frontend and backend functionality. Some examples of Backstage plugins are our Software Catalog, Search, and Software Templates plugins! Each plugin provides a series of well-contained focused features, for example - the Software Catalog contains an entity ingestion engine, an optimized query layer for fetching entity information and a series of UI elements that provide list and detail functionality for entities. Some plugins allow modules which supplement existing plugin-level functionality, customizing it for specific use cases - a good example here are catalog processor modules which allow for ingesting data from common sources into the catalog. + +:::note Backstage Plugin Naming + +The `backstage-cli new` command scaffolds plugins automatically with the expected naming conventions. We describe the naming conventions below for users who are installing external plugins. + +::: + +You'll generally have multiple packages that combine into a single "plugin". The common naming standard (detailed in [ADR-11](../../architecture-decisions/adr011-plugin-package-structure.md)) is demonstrated below for plugin `x`: + +> `x`: Primary frontend entrypoint, contains frontend-only code for the plugin. + +> `x-backend`: Primary backend entrypoint, contains backend-only code. + +> `x-backend-module-y`: Optional backend module `y` for plugin `x`, contains backend-only code. + +> `x-node`: Shared utilities for consumers of backend plugin `x`, should _NOT_ be used on the frontend. + +> `x-react`: Shared utilities for consumers of frontend plugin `x`, should _NOT_ be used on the backend. + +> `x-common`: Shared utilities for consumers of plugin `x`, can be used across backend and frontend. + +Not all plugins need all of those packages, we recommend starting with just a `x` and `x-backend` package and expanding from there. + +## How do I install a plugin? + +As mentioned above, there's 2 parts to installing a plugin - the frontend and the backend. It's recommended to start with installing the backend plugin to ensure your frontend doesn't run into any weird errors. + +In both cases, you'll want to find the plugin's installation documentation. For most plugins, this is available through that plugin's `README.md` file. For example, the Software Catalog plugin's installation instructions are available through their [backend plugin README](https://github.com/backstage/backstage/blob/850ad502eafc356d940e4f1ce6d32951548bb257/plugins/catalog-backend/README.md#L1) and [frontend plugin README](https://github.com/backstage/backstage/blob/850ad502eafc356d940e4f1ce6d32951548bb257/plugins/catalog/README.md#L1). + +### Installing a Backend Plugin + +Generally, installing a backend plugin is really easy - you just add a + +``` +backend.import(`@scope/package`) +``` + +to your `packages/backend/src/index.ts` file alongside the other entries. Saving the file will trigger a hot reload and just like that your new plugin is available and usable. For advanced cases, there may be required config for the plugin that you'll have to set. That config will (or should) be documented by the plugin in their `README`. + +You may also need to add backend modules to provide the additional functionality in the plugin that you're looking for. Backend modules are further extensions to backend code that can provide tailored functionality, good examples are catalog processor modules that add support for Github, LDAP and AWS software entities. Modules install the exact same way as backend plugins. Installing a module may also require additional configuration, which should also be documented in the plugin's `README`. + +### Installing a Frontend Plugin + +Frontend plugins have multiple entrypoints, you should follow the plugin's documentation for how to install it. + +The New Frontend System vastly simplifies this! Keep your eyes peeled for updates. + +## Finding plugins + +The open source community already has a host of plugins that solve many common asks - we recommend you look through [the plugin directory](https://backstage.io/plugins) before you go about creating your own! + +You can find other community maintained plugins in the [Community Plugins Repository](https://github.com/backstage/community-plugins)! + +## Next Steps + +If you're chomping at the bit to write your own plugin, you can move to the `plugins` Golden Path. We recommend you make a note to come back and finish this Golden Path to get more information on maintaining a Backstage app long term. + +For the rest of you, let's walk through keeping your Backstage app up to date! diff --git a/docs/golden-path/create-app/keeping-backstage-updated.md b/docs/golden-path/create-app/keeping-backstage-updated.md new file mode 100644 index 0000000000..de7d99b2b8 --- /dev/null +++ b/docs/golden-path/create-app/keeping-backstage-updated.md @@ -0,0 +1,166 @@ +--- +id: keeping-backstage-updated +sidebar_label: 006 - Keep Backstage updated +title: 006 - Keeping Backstage up to date +--- + +Audience: Developers and Admins + +:::note Note +To better understand the concepts in this section, it's recommended to have an understanding of [Monorepos](https://semaphoreci.com/blog/what-is-monorepo), [Semantic Versioning](https://semver.org) and [CHANGELOGs](https://keepachangelog.com). +::: + +## Summary + +Backstage is always improving, so it's a good idea to stay in sync with the +latest releases. Backstage is more of a library than an application or service; +similar to `create-react-app`, the `@backstage/create-app` tool gives you a +starting point that's meant to be evolved. + +## Updating Backstage versions with backstage-cli + +The Backstage CLI has a command to bump all `@backstage` packages and +dependencies you're using to the latest versions: +[versions:bump](https://backstage.io/docs/tooling/cli/03-commands#versionsbump). + +```bash +yarn backstage-cli versions:bump +``` + +The reason for bumping all `@backstage` packages at once is to maintain the +dependencies that they have between each other. + +
+:::tip + +To make the version bump process even easier and more streamlined we highly recommend using the [Backstage yarn plugin](#managing-package-versions-with-the-backstage-yarn-plugin) + +::: + +By default the bump command will upgrade `@backstage` packages to the latest `main` release line which is released monthly. For those in a hurry that want to track the `next` release line which releases weekly can do so using the `--release next` option. + +```bash +yarn backstage-cli versions:bump --release next +``` + +If you are using other plugins you can pass in the `--pattern` option to update +more than just the `@backstage/*` dependencies. + +```bash +yarn backstage-cli versions:bump --pattern '@{backstage,roadiehq}/*' +``` + +## Following create-app template changes + +The `@backstage/create-app` command creates the initial structure of your +Backstage installation from a **template**. The source of this template in the +Backstage repository is updated periodically, but your local `app` and `backend` +packages are established at `create-app` time and won't automatically get these +template updates. + +For this reason, any changes made to the template are documented along with +upgrade instructions in the +[changelog](https://github.com/backstage/backstage/blob/master/packages/create-app/CHANGELOG.md) +of the `@backstage/create-app` package. We recommend peeking at this changelog +for any applicable updates when upgrading packages. As an alternative, the +[Backstage Upgrade Helper](https://backstage.github.io/upgrade-helper/) provides +a consolidated view of all the changes between two versions of Backstage. You +can find the current version of your Backstage installation in `backstage.json` located in the root of your backstage repository. + +## Managing package versions with the Backstage yarn plugin + +The Backstage yarn plugin makes it easier to manage Backstage package versions, +by determining the appropriate version for each package based on the overall +Backstage version in `backstage.json`. This avoids the need to update every +package.json across your Backstage monorepo, and means that when adding new +`@backstage` dependencies, you don't need to worry about figuring out the right +version to use to match the currently-installed release of Backstage. + +### Requirements + +In order to use the yarn plugin, you'll need to be using yarn 4.1.1 or greater. + +### Installation + +To install the yarn plugin, run the following command in your Backstage +monorepo: + +```bash +yarn plugin import https://versions.backstage.io/v1/tags/main/yarn-plugin +``` + +The resulting changes in the file system should be committed to your repo. + +:::tip + +For best results it's ideal to add the Backstage Yarn plugin when you are about to do a Backstage upgrade as it will make it easier to confirm everything is working. + +::: + +### Usage + +When the yarn plugin is installed, versions for currently-released `@backstage` +packages can be replaced in package.json with the string `"backstage:^"`. This +instructs yarn to resolve the version based on the overall Backstage version in +`backstage.json`. + +:::tip + +The `backstage.json` is key for the plugin to work, make sure this file is included in your CI/CD pipelines and/or any Container builds. + +::: + +The `backstage-cli versions:bump` command documented above will detect the +installation of the yarn plugin, and when it's installed, will automatically +migrate dependencies across the monorepo to use it. + +## More information on dependency mismatches + +Backstage is structured as a monorepo with +[Yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). This means +the `app` and `backend` packages, as well as any custom plugins you've added, +are separate packages with their own `package.json` and dependencies. + +When a given dependency version is the _same_ between different packages, the +dependency is hoisted to the main `node_modules` folder in the monorepo root to +be shared between packages. When _different_ versions of the same dependency are +encountered, Yarn creates a `node_modules` folder within a particular package. +This can lead to multiple versions of the same package being installed and used +in the same app. + +All Backstage core packages are implemented in such as way that package +duplication is **not** a problem. For example, duplicate installations of +packages like `@backstage/core-plugin-api`, `@backstage/core-components`, +`@backstage/plugin-catalog-react`, and `@backstage/backend-plugin-api` are all +acceptable. + +While package duplication might be acceptable in many cases, you might want to +deduplicate packages for the purpose of optimizing bundle size and installation +speed. We recommend using deduplication utilities such as `yarn dedupe` to trim +down the number of duplicate packages. + +## Proxy + +The Backstage CLI uses [global-agent](https://www.npmjs.com/package/global-agent) and `undici` to configure HTTP/HTTPS proxy settings using environment variables. This allows you to route the CLI’s network traffic through a proxy server, which can be useful in environments with restricted internet access. + +Additionally, `yarn` needs a proxy too (sometimes), when in environments with restricted internet access. It uses different settings than the other modules. If you decide to use the backstage yarn plugin [mentioned above](#plugin), you will need to set additional proxy values. +If you will always need proxy settings in all environments and situations, you can add `httpProxy` and `httpsProxy` values to [the yarnrc.yml file](https://yarnpkg.com/configuration/yarnrc). If some environments need it (say a developer workstation) but other environments do not (perhaps a CI build server running on AWS), then you may not want to update the yarnrc.yml file but just set environment variables `YARN_HTTP_PROXY` and `YARN_HTTPS_PROXY` in the environments/situations where you need to proxy. + +**If you plan to use the backstage yarn plugin, you will need these extra yarn proxy settings to both install the plugin and run the `versions:bump` command**. If you do not plan to use the backstage yarn plugin, it seems like the global agent proxy settings alone are sufficient. + +### Example Configuration + +```bash +export HTTP_PROXY=http://proxy.company.com:8080 +export HTTPS_PROXY=https://secure-proxy.company.com:8080 +export NO_PROXY=localhost,internal.company.com +export GLOBAL_AGENT_HTTP_PROXY=${HTTP_PROXY} +export GLOBAL_AGENT_HTTPS_PROXY=${HTTPS_PROXY} +export GLOBAL_AGENT_NO_PROXY=${NO_PROXY} +export YARN_HTTP_PROXY=${HTTP_PROXY} # optional +export YARN_HTTPS_PROXY=${HTTPS_PROXY} # optional +``` + +## Rollback migrations + +In some cases you could need to downgrade Backstage instance due to some problem or maybe because you are using a test environment to validate the new version of Backstage. You can check the [Manual Rollback using Knex](../../tutorials/manual-knex-rollback.md) guide to know how to rollback migrations using Knex. diff --git a/docs/golden-path/create-app/local-development.md b/docs/golden-path/create-app/local-development.md new file mode 100644 index 0000000000..2c81c2c643 --- /dev/null +++ b/docs/golden-path/create-app/local-development.md @@ -0,0 +1,57 @@ +--- +id: local-development +title: 002 - Local development +--- + +Your Backstage app is fully installed and ready to be run! Now that the installation is complete, you can go to the application directory and start the app using the `yarn start` command. The `yarn start` command will run both the frontend and backend as separate processes (named `[0]` and `[1]`) in the same window. + +```bash +cd my-backstage-app # your app name +yarn start +``` + +![Screenshot of the command output, with the message webpack compiled successfully](../../assets/getting-started/startup.png) + +Here again, there's a small wait for the frontend to start up. Once the frontend is built, your browser window should automatically open. + +:::tip Browser window didn't open + +When you see the message `[0] webpack compiled successfully`, you can navigate directly to `http://localhost:3000` to see your Backstage app. + +::: + +Once its spun up, you should see something similar to the below. + +![Screenshot of the Backstage portal](../../assets/getting-started/portal.png) + +## Architecture of local development + +:::note Deploy architecture + +This section only touches on local development, we'll walk through what a Golden Path production architecture looks like in the `deployment` Golden Path. + +::: + +Now that you have that running, let's talk through what you just set up. You have 2 commands running as part of `yarn start` - the website that is stored at `packages/app` and the backend stored at `packages/backend`. + +The website listens on port `3000` by default. It's a React app with some extra flavor to provide strong plugin-friendly defaults. For local development, we use `rspack` for fast compilation and near-instant feedback. + +The backend listens on port `7007` by default. It is a NodeJS app that has among other things an HTTP server through `express` and talks to a database. + +Locally, we use `sqlite` for the database. This is a fast in-memory database that is perfect for local development. Because of its ephemeral nature, you shouldn't rely on the database to keep data across `yarn start`s. We _do_ however, maintain the database across hot reloads. + +Speaking of hot reloads, these are supported for both the frontend and backend. + +In the frontend, whenever you save a file used by your React app, after a slight delay, you should see a message like + +``` +Rspack compiled successfully +``` + +In the backend, you should see a + +``` +Change detected, restarting the development server... +``` + +followed by init logs from your server. diff --git a/docs/golden-path/create-app/logging-in.md b/docs/golden-path/create-app/logging-in.md new file mode 100644 index 0000000000..a45a89b7a2 --- /dev/null +++ b/docs/golden-path/create-app/logging-in.md @@ -0,0 +1,35 @@ +--- +id: logging-in +title: 004 - Logging into your instance +description: Getting up and running with Backstage and your identity provider +--- + +Audience: Developers, Admins + +## Summary + +This guide will provide a quick tutorial on how to log in to your Backstage instance. It should be used as both an introduction to Backstage's authentication system as well as a debugging guide for any issues you may have while logging in. + +## Prerequisites + +You should have completed the GitHub OAuth app setup defined in [the authentication tutorial](../../getting-started/config/authentication.md). + +## 1. Login to Backstage + +Run your Backstage app with `yarn start`. Navigate to `http://localhost:3000`. + +If you're not already logged in, you should see a login screen like this, + +![Screenshot of the login screen](../../assets/getting-started/login-screen.png) + +To login, you should choose the "GitHub" provider and click the "Sign in" button. This will redirect you to a GitHub OAuth page. Verify that the scopes mentioned on that page match the setup you did in [the authentication tutorial](../../getting-started/config/authentication.md). Once you click "Confirm", you will be brought back to the Backstage interface and signed in! + +If you are already logged in, you will be automatically brought to your Backstage instance. + +## 2. Verify that you're logged in + +Once you've logged in, find the "Settings" item in the navigation bar to the left. Click it and you will see your profile. If you see your profile picture and name from GitHub here, congratulations! You've successfully set up a GitHub authentication integration. + + + +If you don't see your profile picture and name, check that you followed all of the steps in [the authentication tutorial](../../getting-started/config/authentication.md). If you have, search for similar issues on [the Discord server](https://discord.gg/backstage-687207715902193673). diff --git a/docs/golden-path/create-app/npx-create-app.md b/docs/golden-path/create-app/npx-create-app.md new file mode 100644 index 0000000000..8ee016f41f --- /dev/null +++ b/docs/golden-path/create-app/npx-create-app.md @@ -0,0 +1,117 @@ +--- +id: npx-create-app +title: '001 - Scaffolding' +--- + +Audience: Developers and Admins + +:::note Note +It is not required, although recommended to have a basic understanding of [Yarn](https://www.pluralsight.com/guides/yarn-a-package-manager-for-node-js) and [npm](https://docs.npmjs.com/about-npm) before starting this guide. +::: + +## Summary + +This guide walks through how to get started creating your very own Backstage customizable app. This is the first step in evaluating, developing on, or demoing Backstage. + +By the end of this guide, you will have a standalone Backstage installation running locally with a `SQLite` database and demo content. + +:::caution Organization customization + +To be clear, this is not a production-ready installation, and it does not contain information specific to your organization. You will learn how to customize Backstage for your use case through this guide. + +::: + +## Prerequisites + +This guide also assumes a basic understanding of working on a Linux based operating system and have some experience with the terminal, specifically, these commands: `npm`, `yarn`. + +- Access to a Unix-based operating system, such as Linux, macOS or + [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) +- A GNU-like build environment available at the command line. + For example, on Debian/Ubuntu you will want to have the `make` and `build-essential` packages installed. + On macOS, you will want to have run `xcode-select --install` to get the XCode command line build tooling in place. +- An account with elevated rights to install the dependencies +- `curl` or `wget` installed +- Node.js [Active LTS Release](../../overview/versioning-policy.md#nodejs-releases) installed using one of these + methods: + - Using `nvm` (recommended) + - [Installing nvm](https://github.com/nvm-sh/nvm#install--update-script) + - [Install and change Node version with nvm](https://nodejs.org/en/download/package-manager/#nvm) + - Node 20 is a good starting point, this can be installed using `nvm install lts/iron` + - [Binary download](https://nodejs.org/en/download/) + - [Package manager](https://nodejs.org/en/download/package-manager/) + - [Using NodeSource packages](https://github.com/nodesource/distributions/blob/master/README.md) +- `yarn` [Installation](https://yarnpkg.com/getting-started/install) + - Backstage currently uses Yarn 4.4.1, once you've ran `corepack enable` you'll want to then run `yarn set version 4.4.1` +- `git` [installation](https://github.com/git-guides/install-git) + +## Scaffold your new Backstage app + +## 1. Create your Backstage App + +To scaffold your new Backstage app, we'll be running an interactive command. Before you run the command, you should open a terminal and move your current working directory somewhere you're comfortable creating a new directory. + +The wizard for this command will ask what name you want to have for your new app. That name will match the folder that we create for you. + +When you run the command, you'll see an output like this. + +![create app](../../assets/getting-started/create-app-output.png) + +And when it finishes, you'll have a working Backstage app (with example data)! + +Now, that we know what it does, let's actually scaffold some code! + +```bash +npx @backstage/create-app@latest +``` + +This may take a few minutes to fully install everything. Don't stress if the loading seems to be spinning nonstop, there's a lot going on in the background. + +:::note + +If this fails on the `yarn install` step, it's likely that you will need to install some additional dependencies which are used to configure `isolated-vm`. You can find out more in their [requirements section](https://github.com/laverdet/isolated-vm#requirements), and then run `yarn install` manually again after you've completed those steps. + +::: + +## Structure of your app + +### General folder structure + +Below is a simplified layout of the files and folders generated when creating an app. + +``` +app +├── app-config.yaml +├── catalog-info.yaml +├── package.json +└── packages +   ├── app +   └── backend +``` + +- **app-config.yaml**: Main configuration file for the app. See + [Configuration](https://backstage.io/docs/conf/) for more information. +- **catalog-info.yaml**: Catalog Entities descriptors. See + [Descriptor Format of Catalog Entities](https://backstage.io/docs/features/software-catalog/descriptor-format) + to get started. +- **package.json**: Root package.json for the project. _Note: Be sure that you + don't add any npm dependencies here as they probably should be installed in + the intended workspace rather than in the root._ +- **packages/**: Lerna leaf packages or "workspaces". Everything here is going + to be a separate package, managed by lerna. +- **packages/app/**: A fully functioning Backstage frontend app that acts as a + good starting point for you to get to know Backstage. +- **packages/backend/**: We include a backend that helps power features such as + [Authentication](https://backstage.io/docs/auth/), + [Software Catalog](https://backstage.io/docs/features/software-catalog/), + [Software Templates](https://backstage.io/docs/features/software-templates/) + and [TechDocs](https://backstage.io/docs/features/techdocs/) + amongst other things. + +## Common Issues + +- App is not running on port X: Backstage uses ports `3000` and `7007` as its default frontend and backend ports. Make sure that your commands haven't exited with errors. For remote or containerized setups, make sure those ports above are accessible. + +## Next Steps + +Now that you have a scaffolded app, let's learn how to start it locally for development! diff --git a/docs/golden-path/plugins/backend/001-first-steps.md b/docs/golden-path/plugins/backend/001-first-steps.md new file mode 100644 index 0000000000..1850ba52c1 --- /dev/null +++ b/docs/golden-path/plugins/backend/001-first-steps.md @@ -0,0 +1,55 @@ +--- +id: 001-first-steps +sidebar_label: 001 - Scaffolding the plugin +title: How to scaffold a new plugin? +--- + +# Scaffolding a new plugin + + + +## `yarn new` + +A new, bare-bones backend plugin package can be created by issuing the following +command in your Backstage repository's root directory and selecting `backend-plugin`: + +```sh +yarn new +``` + +You will be asked to supply a name for the plugin. This is an identifier that +will be part of the NPM package name, so make it short and containing only +lowercase characters separated by dashes, for our example, you should provide `todo`. For plugins you may write in the future, this should be an easy to remember indicator of what this plugins does, like if it's a +package that adds an integration with a system named Carmen, you would want to name it `carmen`. + +This will create a new NPM package with a package name something like `@internal/plugin-carmen-backend`, depending on the other flags passed to the `new` command, and your settings for the `new` command in your root `package.json`. For future reference, we also support additional flags and configuration. Learn more at [the CLI docs](../../../tooling/cli/03-commands.md#new). + +Creating the plugin will take a little while, so be patient. If it runs with no issues, it will run the initial installation and build commands, so that your package is ready to be hacked on! + +Once the commands complete, you should see a new folder `plugins/todo-backend` with content like the below tree: + +``` +/ <- your Backstage app's root directory + /plugins/ + /todo-backend/ + package.json + README.md + eslintrc.js + /dev/ + index.ts + /src/ + plugin.ts + index.ts + router.ts + /services/ + /TodoListService/ + TodoListService.ts + types.ts + index.ts +``` + + + +### FAQs + + diff --git a/docs/golden-path/plugins/backend/002-poking-around.md b/docs/golden-path/plugins/backend/002-poking-around.md new file mode 100644 index 0000000000..35de3c4d47 --- /dev/null +++ b/docs/golden-path/plugins/backend/002-poking-around.md @@ -0,0 +1,34 @@ +--- +id: 002-poking-around +sidebar_label: 002 - Poking around +title: 002 - Poking around +--- + +## Default plugin functionality + +By default, that plugin that you just created hosts a simple todo list application. It exposes an HTTP API at `http://localhost:7007/api/todo/todos` that allows you to create TODOs, list existing TODOs, and get a specific TODO. It stores those TODOs in memory, which means that you would lose all of your TODOs if you restarted your application. It also allows you to tag TODOs with a Software Catalog entity, which will be useful for our frontend integration. + +To make this plugin production ready, we'll need to adjust a few things, + +1. Write our TODOs to a database so they don't get lost on restart. +2. Write some proper tests to make sure everything works the way we expect. +3. Get user feedback. + +## Testing locally + +Before we jump in to making this plugin ready to ship, let's walk through how to run it locally. If you open your backend plugin's manifest (`plugins/todo-backend/package.json`), and look at the `scripts` section, you'll notice a few important commands. The ones relevant to use right now are + +1. `yarn start` - Starts a local development server using the content in `dev/index.ts` as the backend. +2. `yarn test` - Runs all of the tests for your backend plugin. + +If you run `yarn start`, you should see a custom backend for just your plugin start up. This will simplify plugin development and iteration for you or your team by easily testing out new features in just your plugin - just make sure you add what you need to the global `packages/backend`. The important log for us to look for is + +``` +2025-06-08T16:14:53.229Z rootHttpRouter info Listening on :7007 +``` + +This indicates that your HTTP server is up and running and we can start sending test HTTP requests. Grab your favorite HTTP client and let's get testing! If you aren't sure what to use, I'd recommend the `humao.rest-client` VSCode extension which can easily be run in VSCode itself with very little extra set up. + +``` + +``` diff --git a/docs/golden-path/plugins/backend/meta.md b/docs/golden-path/plugins/backend/__meta__.md similarity index 76% rename from docs/golden-path/plugins/backend/meta.md rename to docs/golden-path/plugins/backend/__meta__.md index 4507a934d5..e261a8f970 100644 --- a/docs/golden-path/plugins/backend/meta.md +++ b/docs/golden-path/plugins/backend/__meta__.md @@ -88,44 +88,6 @@ After verifying everything, introduce the problem of persistence - the todos are Saving values to the database. Writing a migrations file. Plumbing through the database service. -## Integrations - -Now that our plugin is ready for prime time, let's see how we can really leverage the rest of the Backstage ecosystem. Backstage provides a set of core features out of the box, namely, the Software Catalog, Search, Permissions, and Notifications. - -### Catalog - -We want to show our todos as separate Catalog entities. How can we make this happen? - -### Search - -We want to make our todos searchable. - -### Permissions - -We only want users to be able to find their own todos. - -### Notifications - -We want to set an alarm time for todos that sends a notification when the time is met. - ## SCM Integrations Our users love the new plugin, and now they want it to automatically fetch todos from their source code. - -## Additional Resources and Further Reading - -- **Real-world Implementations and Lessons** - - - [Case studies and examples from the community](https://github.com/backstage/community#newsletters). - - Best practices derived from mature implementations. - - [Existing open-source community-maintained plugins](https://github.com/backstage/community-plugins). - -- **Resource Compendium** - - - [Backstage Glossary](https://backstage.io/docs/references/glossary) of key terms. - - Recommended readings and tools for advanced developers. - -- **Certification and Learning Pathways** - - Pathways to deepen your understanding and expertise in plugin development for Backstage. - -Stay tuned for detailed exploration and guidance in each of these modules. We're excited to accompany you on your plugin development journey! diff --git a/docs/golden-path/plugins/backend/recap.md b/docs/golden-path/plugins/backend/recap.md new file mode 100644 index 0000000000..94eca8fafe --- /dev/null +++ b/docs/golden-path/plugins/backend/recap.md @@ -0,0 +1,23 @@ +## Learning Recap + +With this golden path, you learned how to, + + + +## Additional Resources and Further Reading + +- **Real-world Implementations and Lessons** + + - [Case studies and examples from the community](https://github.com/backstage/community#newsletters). + - Best practices derived from mature implementations. + - [Existing open-source community-maintained plugins](https://github.com/backstage/community-plugins). + +- **Resource Compendium** + + - [Backstage Glossary](https://backstage.io/docs/references/glossary) of key terms. + - Recommended readings and tools for advanced developers. + +- **Certification and Learning Pathways** + - Pathways to deepen your understanding and expertise in plugin development for Backstage. + +Stay tuned for detailed exploration and guidance in each of these modules. We're excited to accompany you on your plugin development journey! diff --git a/docs/golden-path/plugins/backend/todo.http b/docs/golden-path/plugins/backend/todo.http new file mode 100644 index 0000000000..932dcb76e4 --- /dev/null +++ b/docs/golden-path/plugins/backend/todo.http @@ -0,0 +1,12 @@ +POST http://localhost:7007/api/todo/todos +Content-Type: application/json + +{ + "title": "My First TODO" +} + +### + +GET http://localhost:7007/api/todo/todos + +### \ No newline at end of file diff --git a/docs/golden-path/plugins/index.md b/docs/golden-path/plugins/index.md new file mode 100644 index 0000000000..616c2c0c36 --- /dev/null +++ b/docs/golden-path/plugins/index.md @@ -0,0 +1,33 @@ +--- +id: index +sidebar_label: Backstage Plugins! +title: How to create plugins with Backstage +--- + +### Prerequisites + +- We expect that you have finished the create-app golden path. + +### Scenario + +You have an awesome idea to create a todo list tracker in your Backstage instance at an upcoming company hackathon. Backstage is supposed to unify all of our information after all, it should track future tasks to complete as well! + +Many of the great Backstage plugins started in a similar way, a developer noticed that others on their team or in the company were: + +- Wasting time manually compiling spreadsheets filled with error-prone data +- Spending hours every week trying to find that one specific link from that one site +- A million other problems that impact developer flow or are just toil + + And they decided to create a shared plugin in Backstage to solve that problem. + +This guide will teach you how to deliver high-quality Backstage plugins with confidence. Both so you can impress everyone at the hackathon and set yourself up for success when you inevitably are asked to make your plugin production-ready. + +### Structure + +To start, this guide will walk through creating a backend plugin. You'll get your feet wet working with an HTTP API, a database and the Backstage backend system. Then, we'll move to the frontend, where we'll show you how to create a new page that's visible to your Backstage users as well as how to call your API. Finally, we'll walk through some common integrations you may want to consider as you write plugins. + +### Next Steps + +- [Why build plugins?](./why-build-plugins.md) +- [Sustainable plugin development](./sustainable-plugin-development.md) +- [Golden path: Backend plugins](./backend/001-first-steps.md) diff --git a/docs/golden-path/plugins/integrations/__meta__.md b/docs/golden-path/plugins/integrations/__meta__.md new file mode 100644 index 0000000000..2d8df8136e --- /dev/null +++ b/docs/golden-path/plugins/integrations/__meta__.md @@ -0,0 +1,19 @@ +## Integrations + +Now that our plugin is ready for prime time, let's see how we can really leverage the rest of the Backstage ecosystem. Backstage provides a set of core features out of the box, namely, the Software Catalog, Search, Permissions, and Notifications. + +### Catalog + +We want to show our todos as separate Catalog entities. How can we make this happen? + +### Search + +We want to make our todos searchable. + +### Permissions + +We only want users to be able to find their own todos. + +### Notifications + +We want to set an alarm time for todos that sends a notification when the time is met. diff --git a/docs/golden-path/plugins/sustainable-plugin-development.md b/docs/golden-path/plugins/sustainable-plugin-development.md new file mode 100644 index 0000000000..82d529d6e1 --- /dev/null +++ b/docs/golden-path/plugins/sustainable-plugin-development.md @@ -0,0 +1,29 @@ +--- +id: sustainable-plugin-development +sidebar_label: Sustainable plugin development +title: Sustainably developing plugins in Backstage +--- + +Plugins are not created in a vacuum, they generally solve a customer ask, be that + +- a business problem, like showing cloud spend +- a new integration, like showing data from an external vendor such as Pagerduty +- a developer pain point, like organizing information from disjoint or disorganized systems. + +To ensure that your plugin lives the test of time, you'll need to figure out how to keep it up-to-date, + +### Finding your stakeholders + + + +### Iterating on your plugin + +In many cases, your first version of a plugin will cut a few corners - this is a good sign, you're more focused on delivering a strong use case to continue development than over-indexing on your initial code. It may be temporary after all, if you don't get the response you're looking for! + +So, how do you decide when you should iterate on your plugin? + + + +### Ensuring the success of your plugin + + diff --git a/docs/golden-path/plugins/why-build-plugins.md b/docs/golden-path/plugins/why-build-plugins.md new file mode 100644 index 0000000000..b0e1be0a98 --- /dev/null +++ b/docs/golden-path/plugins/why-build-plugins.md @@ -0,0 +1,33 @@ +--- +id: why-build-plugins +sidebar_label: Why build plugins? +title: Introduction to the Value and Impact of Plugins within Backstage +--- + +Backstage plugins are essential components that enable the integration of various tools and services into a unified developer portal. Here’s a detailed look at why building plugins for Backstage can be highly beneficial: + +## Enhancing Developer Productivity + +Plugins in Backstage centralize and simplify access to tools, reducing the time developers spend switching between different systems. By providing a consistent interface and user experience, plugins minimize cognitive load and streamline workflows, allowing developers to focus more on coding and less on tool management. Plugins can leverage platform APIs and reusable UI components to integrate external data and services seamlessly. + +## Customizable and Extensible Platform + +Backstage's plugin architecture is designed to be highly flexible, enabling the integration of nearly any infrastructure or software development tool. This extensibility allows organizations to tailor Backstage to meet their specific needs, integrating internal tools, third-party services, and other custom functionalities seamlessly. For detailed guidelines on plugin development, refer to the [Backstage Plugin Development documentation](https://backstage.io/docs/plugins/plugin-development/). + +## Improved Collaboration and Knowledge Sharing + +Plugins facilitate better collaboration among teams by consolidating documentation, code repositories, CI/CD pipelines, and monitoring tools in one place. This centralization makes it easier for team members to find information, share insights, and collaborate on projects, enhancing overall team productivity and coherence. + +## Consistency and Best Practices + +By adhering to Backstage’s design guidelines, plugins ensure a consistent user experience across the platform. This consistency helps in maintaining usability and reducing the learning curve for new users, promoting the adoption of best practices within development teams. More details can be found in the [Introduction to Plugins](https://backstage.io/docs/plugins/) section. + +## Scalability and Maintenance + +Backstage plugins are designed to be modular and independent, allowing for easy updates and maintenance without affecting the overall system. This modularity supports horizontal scalability, where each plugin can be scaled independently according to the needs of the application, ensuring robust performance and reliability. For more on structuring and connecting plugins, see the [Structure of a Plugin](https://backstage.io/docs/plugins/structure-of-a-plugin) documentation. + +## Community and Ecosystem Growth + +Developing and contributing plugins to the Backstage community helps in expanding the ecosystem. Open-source contributions foster innovation and collaboration, allowing developers to leverage a wide range of existing plugins and avoid reinventing the wheel. This collaborative environment accelerates the development of new features and enhances the overall value of the Backstage platform. + +Building plugins for Backstage significantly enhances developer productivity, promotes best practices, supports scalability, and fosters community growth. These plugins transform Backstage into a comprehensive developer portal that can adapt to the unique needs of any organization. For more detailed information, refer to the [Backstage Plugin Development documentation](https://backstage.io/docs/plugins/plugin-development/) and the [Introduction to Plugins](https://backstage.io/docs/plugins/). diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 4a40b25361..f245e960ea 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -58,7 +58,7 @@ To receive the `repository.transferred` event, the new owner account must have t ::: -When creating the webhook in GitHub the "Payload URL" will looks something along these lines: `https:///api/events/http/github` and the "Content Type" should be `application/json`. +When creating the webhook in GitHub the "Payload URL" will looks something along these lines: `https:///api/events/http/github` and the "Content Type" should be `application/json`. The GitHub Webhooks UI will send a trial event to validate it can connect when you save your new Webhook. It is possible to retry this trial event if it fails and you want to send it again. Additionally there is a Recent Deliveries tab you can use to validate that the events are being fired should you need to do any later troubleshooting. @@ -210,6 +210,8 @@ catalog: filters: # optional filters branch: 'develop' # optional string repository: '.*' # optional Regex + pageSizes: + repositories: 25 wildcardProviderId: organization: 'new-org' # string catalogPath: '/groups/**/*.yaml' # this will search all folders for files that end in .yaml @@ -308,6 +310,10 @@ If you do so, `default` will be used as provider ID. The amount of time that should pass before the first invocation happens. - **`scope`** _(optional)_: `'global'` or `'local'`. Sets the scope of concurrency control. +- **`pageSizes`** _(optional)_: + Configure page sizes for GitHub GraphQL API queries. This can help prevent `RESOURCE_LIMITS_EXCEEDED` errors. + - **`repositories`** _(optional)_: + Number of repositories to fetch per page. Defaults to `25`. Reduce this value if hitting API resource limits. ## GitHub API Rate Limits diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md index 473d408b0b..6526183f2d 100644 --- a/docs/integrations/github/org.md +++ b/docs/integrations/github/org.md @@ -79,6 +79,10 @@ catalog: initialDelay: { seconds: 30 } frequency: { hours: 1 } timeout: { minutes: 50 } + pageSizes: + teams: 25 + teamMembers: 50 + organizationMembers: 50 - id: ghe githubUrl: https://ghe.mycompany.com orgs: ['internal-1', 'internal-2', 'internal-3'] @@ -94,6 +98,13 @@ Directly under the `githubOrg` is a list of configurations, each entry is a stru - `githubUrl`: The target that this provider should consume - `orgs` (optional): The list of the GitHub orgs to consume. If you only list a single org the generated group entities will use the `default` namespace, otherwise they will use the org name as the namespace. By default the provider will consume all accessible orgs on the given GitHub instance (support for GitHub App integration only). - `schedule`: The refresh schedule to use, matches the structure of [`SchedulerServiceTaskScheduleDefinitionConfig`](https://backstage.io/docs/reference/backend-plugin-api.schedulerservicetaskscheduledefinitionconfig/) +- `pageSizes` (optional): Configure page sizes for GitHub GraphQL API queries to prevent `RESOURCE_LIMITS_EXCEEDED` errors. You can configure the following page sizes: + + - `teams`: Number of teams to fetch per page when querying organization teams (default: 25) + - `teamMembers`: Number of team members to fetch per page when querying team members (default: 50) + - `organizationMembers`: Number of organization members to fetch per page (default: 50) + + Reducing page sizes will result in more API calls and slightly longer sync times, but will prevent API resource limits for organizations with large number of teams and members. ### Events Support diff --git a/docs/notifications/index.md b/docs/notifications/index.md index 59ff2962ed..dce58d3214 100644 --- a/docs/notifications/index.md +++ b/docs/notifications/index.md @@ -164,6 +164,61 @@ You can customize the origin names shown in the UI by passing an object where th Each notification processor will receive its own row in the settings page, where the user can enable or disable notifications from that processor. +### Default notification settings + +You can configure default notification settings for all users in your `app-config.yaml` file. This allows you to set up notification preferences globally, such as disabling specific channels or origins by default, implementing an opt-in strategy instead of opt-out. + +#### Channel-level defaults + +You can set a default enabled state for an entire channel. When set to `false`, the channel uses an opt-in strategy where notifications are disabled by default unless explicitly enabled by the user or for specific origins. + +```yaml +notifications: + defaultSettings: + channels: + - id: 'Web' + enabled: false # Opt-in strategy: channel disabled by default + - id: 'Email' + enabled: true # Opt-out strategy: channel enabled by default (default behavior) +``` + +#### Origin-level defaults + +You can also configure defaults for specific origins within a channel: + +```yaml +notifications: + defaultSettings: + channels: + - id: 'Web' + enabled: true # Channel is enabled by default + origins: + - id: 'plugin:scaffolder' + enabled: false # Disable scaffolder notifications by default + - id: 'plugin:catalog' + enabled: true # Enable catalog notifications by default +``` + +#### Topic-level defaults + +For even more granular control, you can set defaults for specific topics within origins: + +```yaml +notifications: + defaultSettings: + channels: + - id: 'Email' + enabled: false # Email is opt-in by default + origins: + - id: 'plugin:catalog' + enabled: true # But catalog notifications are enabled + topics: + - id: 'entity:validation:error' + enabled: false # Except validation errors +``` + +**Note:** If a channel's `enabled` flag is not set, it defaults to `true` for backwards compatibility. When a channel is set to `enabled: false`, all origins within that channel default to disabled unless explicitly enabled. + ### Automatic notification cleanup Notifications are deleted automatically after a certain period of time to prevent the database from growing indefinitely diff --git a/docs/plugins/backend-plugin.md b/docs/plugins/backend-plugin.md index bfd210aeb9..9b8b63fc89 100644 --- a/docs/plugins/backend-plugin.md +++ b/docs/plugins/backend-plugin.md @@ -48,11 +48,20 @@ This will think for a bit, and then say `Listening on :7007`. In a different terminal window, now run ```sh -curl localhost:7007/api/carmen/health +curl localhost:7007/api/carmen/todos ``` -This should return `{"status":"ok"}`. Success! Press `Ctrl + c` to stop it -again. +You should see the following response: + +```json +{ + "items": [] +} +``` + +:::note Note: The route shown here matches the default in the current backend plugin template. If you want a `/health` endpoint for health checks, you can add it to your router yourself. + +::: ## Developing your Backend Plugin diff --git a/docs/releases/v1.45.0-next.1-changelog.md b/docs/releases/v1.45.0-next.1-changelog.md new file mode 100644 index 0000000000..098dd21e02 --- /dev/null +++ b/docs/releases/v1.45.0-next.1-changelog.md @@ -0,0 +1,9366 @@ +# Release v1.45.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.45.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.45.0-next.1) + +## @techdocs/cli@1.10.2-next.0 + +# @techdocs/cli + +## 1.10.1-next.0 + +### Patch Changes + +- c2a2017: Fix for missing styles due to move to BUI. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-techdocs-node@1.13.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/cli-common@0.1.15 + +## 1.10.0 + +### Minor Changes + +- 43afbe5: Techdocs CLI serve supports automatic refresh, relying on `mkdocs` `watch` feature. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/config@1.3.5 + - @backstage/plugin-techdocs-node@1.13.8 + +## 1.9.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/plugin-techdocs-node@1.13.8-next.1 + +## 1.9.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-techdocs-node@1.13.8-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + +## 1.9.8 + +### Patch Changes + +- db63208: Fixed an issue where `@techdocs/cli serve` command did not pick up the latest changes to TechDocs. +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-techdocs-node@1.13.7 + +## 1.9.8-next.0 + +### Patch Changes + +- db63208: Fixed an issue where `@techdocs/cli serve` command did not pick up the latest changes to TechDocs. +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-techdocs-node@1.13.7-next.0 + +## 1.9.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-techdocs-node@1.13.6 + +## 1.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-techdocs-node@1.13.6-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + +## 1.9.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-techdocs-node@1.13.5 + +## 1.9.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/plugin-techdocs-node@1.13.5-next.1 + +## 1.9.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4 + +## 1.9.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## 1.9.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## 1.9.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-techdocs-node@1.13.4-next.0 + +## 1.9.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-techdocs-node@1.13.3 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + +## 1.9.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0-next.3 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.3-next.3 + +## 1.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0-next.2 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.3-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + +## 1.9.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0-next.1 + - @backstage/plugin-techdocs-node@1.13.3-next.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.1-next.0 + - @backstage/plugin-techdocs-node@1.13.3-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.0 + - @backstage/plugin-techdocs-node@1.13.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.0-next.2 + - @backstage/plugin-techdocs-node@1.13.2-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.0-next.1 + - @backstage/plugin-techdocs-node@1.13.2-next.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.0-next.0 + - @backstage/plugin-techdocs-node@1.13.2-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.2 + - @backstage/plugin-techdocs-node@1.13.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.2-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.1-next.2 + +## 1.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.2-next.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.1-next.1 + +## 1.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.2-next.0 + - @backstage/plugin-techdocs-node@1.13.1-next.0 + +## 1.9.0 + +### Minor Changes + +- 8de3d2d: Allow configurable optional retries for publisher AWS S3 operations. + +### Patch Changes + +- 69f84ac: Internal update to work with dynamic imports. +- Updated dependencies + - @backstage/backend-defaults@0.8.0 + - @backstage/plugin-techdocs-node@1.13.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.3 + - @backstage/plugin-techdocs-node@1.13.0-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.0-next.1 + +## 1.9.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.0-next.0 + +## 1.9.0-next.0 + +### Minor Changes + +- 8de3d2d: Allow configurable optional retries for publisher AWS S3 operations. + +### Patch Changes + +- 69f84ac: Internal update to work with dynamic imports. +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-techdocs-node@1.13.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.8.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.7.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.12.16 + +## 1.8.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.7.0-next.1 + - @backstage/catalog-model@1.7.3-next.0 + - @backstage/config@1.3.2-next.0 + - @backstage/plugin-techdocs-node@1.12.16-next.1 + - @backstage/cli-common@0.1.15 + +## 1.8.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.7.0-next.0 + - @backstage/catalog-model@1.7.2 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1 + - @backstage/plugin-techdocs-node@1.12.16-next.0 + +## 1.8.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.6.0 + - @backstage/plugin-techdocs-node@1.12.15 + - @backstage/catalog-model@1.7.2 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1 + +## 1.8.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.6.0-next.2 + - @backstage/plugin-techdocs-node@1.12.15-next.2 + - @backstage/catalog-model@1.7.2-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1-next.0 + +## 1.8.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.6.0-next.1 + - @backstage/catalog-model@1.7.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.0 + - @backstage/plugin-techdocs-node@1.12.15-next.1 + +## 1.8.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.6.0-next.0 + - @backstage/plugin-techdocs-node@1.12.15-next.0 + - @backstage/catalog-model@1.7.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.0 + +## 1.8.22 + +### Patch Changes + +- 702f41d: Bumped dev dependencies `@types/node` +- Updated dependencies + - @backstage/config@1.3.0 + - @backstage/backend-defaults@0.5.3 + - @backstage/cli-common@0.1.15 + - @backstage/catalog-model@1.7.1 + - @backstage/plugin-techdocs-node@1.12.13 + +## 1.8.22-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.3-next.3 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.15-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.13-next.3 + +## 1.8.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.3-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.15-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.13-next.2 + +## 1.8.22-next.1 + +### Patch Changes + +- 702f41d: Bumped dev dependencies `@types/node` +- Updated dependencies + - @backstage/cli-common@0.1.15-next.0 + - @backstage/backend-defaults@0.5.3-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.13-next.1 + +## 1.8.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.3-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.13-next.0 + +## 1.8.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1 + - @backstage/plugin-techdocs-node@1.12.12 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.2 + - @backstage/plugin-techdocs-node@1.12.12-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.12-next.1 + +## 1.8.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.12-next.0 + +## 1.8.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/plugin-techdocs-node@1.12.11 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-techdocs-node@1.12.11-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.11-next.1 + +## 1.8.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.11-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2 + - @backstage/plugin-techdocs-node@1.12.9 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.3 + - @backstage/plugin-techdocs-node@1.12.9-next.3 + - @backstage/catalog-model@1.6.0-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.2 + - @backstage/plugin-techdocs-node@1.12.9-next.2 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.9-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.9-next.0 + +## 1.8.16 + +### Patch Changes + +- c964a3d: Import discovery from backend-defaults instead of backend-common +- Updated dependencies + - @backstage/backend-defaults@0.4.0 + - @backstage/plugin-techdocs-node@1.12.8 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.8-next.1 + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.15-next.0 + +### Patch Changes + +- c964a3d: Import discovery from backend-defaults instead of backend-common +- Updated dependencies + - @backstage/backend-defaults@0.3.3-next.0 + - @backstage/plugin-techdocs-node@1.12.7-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.12 + +### Patch Changes + +- 2110d76: Removed `dockerode` dependency. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/plugin-techdocs-node@1.12.5 + - @backstage/cli-common@0.1.14 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## 1.8.12-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.5-next.3 + - @backstage/cli-common@0.1.14-next.0 + - @backstage/backend-common@0.23.0-next.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## 1.8.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.5-next.2 + - @backstage/backend-common@0.23.0-next.2 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.0-next.1 + - @backstage/plugin-techdocs-node@1.12.5-next.1 + +## 1.8.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.22.1-next.0 + - @backstage/plugin-techdocs-node@1.12.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.11 + +### Patch Changes + +- 1a0e009: Fix cookie endpoint mock for `serve` +- Updated dependencies + - @backstage/catalog-model@1.5.0 + - @backstage/backend-common@0.22.0 + - @backstage/plugin-techdocs-node@1.12.4 + +## 1.8.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.22.0-next.1 + - @backstage/plugin-techdocs-node@1.12.4-next.1 + +## 1.8.10-next.0 + +### Patch Changes + +- 1a0e009: Fix cookie endpoint mock for `serve` +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/plugin-techdocs-node@1.12.4-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-techdocs-node@1.12.3 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-techdocs-node@1.12.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.8 + +### Patch Changes + +- 8caf2f7: Fix how the cli server mocks the new auth cookie endpoint. +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/plugin-techdocs-node@1.12.2 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-techdocs-node@1.12.1 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.6 + +### Patch Changes + +- 1bd4596: Removed the `ts-node` dev dependency. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + +## 1.8.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0-next.1 + +## 1.8.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/plugin-techdocs-node@1.11.6-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + +## 1.8.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-techdocs-node@1.11.5-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/cli-common@0.1.13 + +## 1.8.2 + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- d2e3ab9: Updated dependency `dockerode` to `^4.0.0`. +- 6ba64c4: Updated dependency `commander` to `^12.0.0`. +- d8d243c: fix: mkdocs parameter casing +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-techdocs-node@1.11.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.2-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0-next.3 + - @backstage/plugin-techdocs-node@1.11.2-next.3 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0-next.2 + - @backstage/plugin-techdocs-node@1.11.2-next.2 + - @backstage/config@1.1.1 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/cli-common@0.1.13 + +## 1.8.2-next.1 + +### Patch Changes + +- d8d243c: fix: mkdocs parameter casing +- Updated dependencies + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/backend-common@0.21.0-next.1 + - @backstage/plugin-techdocs-node@1.11.2-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0-next.0 + - @backstage/plugin-techdocs-node@1.11.2-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-techdocs-node@1.11.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1-next.2 + - @backstage/plugin-techdocs-node@1.11.1-next.2 + +## 1.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1-next.1 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.1-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + +## 1.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.1-next.0 + +## 1.8.0 + +### Minor Changes + +- d15d483: Add command `--runAsDefaultUser` for `@techdocs/cli generate` to bypass running the docker builds as host user for macOS and Linux. +- b2dccad: Support passing additional `mkdocs-server` CLI parameters (`--dirtyreload`, `--strict` and `--clean`) when run in containerized mode. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0 + - @backstage/plugin-techdocs-node@1.11.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.3 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.0-next.3 + +## 1.8.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.0-next.2 + +## 1.8.0-next.1 + +### Minor Changes + +- b2dccad7b3: Support passing additional `mkdocs-server` CLI parameters (`--dirtyreload`, `--strict` and `--clean`) when run in containerized mode. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.11.0-next.1 + - @backstage/backend-common@0.20.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.0-next.0 + +### Minor Changes + +- d15d483a49: Add command `--runAsDefaultUser` for `@techdocs/cli generate` to bypass running the docker builds as host user for macOS and Linux. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.0 + - @backstage/plugin-techdocs-node@1.11.0-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.7.0 + +### Minor Changes + +- 8600b86820: validate Docker status before running mkdocs server + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.10.0 + - @backstage/backend-common@0.19.9 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.6.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.9-next.2 + - @backstage/plugin-techdocs-node@1.10.0-next.2 + +## 1.6.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.10.0-next.1 + - @backstage/backend-common@0.19.9-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.9-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.9.1-next.0 + +## 1.6.0 + +### Minor Changes + +- d06b30b050: Add possibility to use a mkdocs config file with a different name than `mkdocs. with the serve command using the `--mkdocs-config-file-name\` argument + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 2b6e572051: Restructured tests. +- Updated dependencies + - @backstage/backend-common@0.19.8 + - @backstage/plugin-techdocs-node@1.9.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.6.0-next.2 + +### Minor Changes + +- d06b30b050: Add possibility to use a mkdocs config file with a different name than `mkdocs. with the serve command using the `--mkdocs-config-file-name\` argument + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.8-next.2 + - @backstage/plugin-techdocs-node@1.9.0-next.2 + - @backstage/catalog-model@1.4.3-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.1-next.0 + +## 1.5.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.1 + - @backstage/plugin-techdocs-node@1.8.2-next.1 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/cli-common@0.1.13-next.0 + +## 1.5.2-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 2b6e572051: Restructured tests. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-techdocs-node@1.8.2-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + +## 1.5.0 + +### Minor Changes + +- 10a86bd4ae12: Add optional config and cli option for techdocs to specify default mkdocs plugins. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.5 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-techdocs-node@1.8.0 + - @backstage/cli-common@0.1.12 + +## 1.5.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.2-next.2 + - @backstage/config@1.1.0-next.2 + - @backstage/backend-common@0.19.5-next.3 + - @backstage/cli-common@0.1.12 + - @backstage/plugin-techdocs-node@1.8.0-next.3 + +## 1.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0-next.1 + - @backstage/backend-common@0.19.5-next.2 + - @backstage/catalog-model@1.4.2-next.1 + - @backstage/plugin-techdocs-node@1.8.0-next.2 + - @backstage/cli-common@0.1.12 + +## 1.5.0-next.1 + +### Minor Changes + +- 10a86bd4ae12: Add optional config and cli option for techdocs to specify default mkdocs plugins. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0-next.0 + - @backstage/plugin-techdocs-node@1.8.0-next.1 + - @backstage/backend-common@0.19.5-next.1 + - @backstage/catalog-model@1.4.2-next.0 + - @backstage/cli-common@0.1.12 + +## 1.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.4-next.0 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/plugin-techdocs-node@1.7.6-next.0 + +## 1.4.5 + +### Patch Changes + +- 971bdd6a4732: Bumped internal `nodemon` dependency. +- Updated dependencies + - @backstage/backend-common@0.19.2 + - @backstage/plugin-techdocs-node@1.7.4 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + +## 1.4.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.2-next.2 + - @backstage/plugin-techdocs-node@1.7.4-next.2 + +## 1.4.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.2-next.1 + - @backstage/plugin-techdocs-node@1.7.4-next.1 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + +## 1.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.2-next.0 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/plugin-techdocs-node@1.7.4-next.0 + +## 1.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.1 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/plugin-techdocs-node@1.7.3 + +## 1.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.1-next.0 + - @backstage/catalog-model@1.4.1-next.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/plugin-techdocs-node@1.7.3-next.0 + +## 1.4.3 + +### Patch Changes + +- 68a21956ef52: Remove reference to deprecated import +- Updated dependencies + - @backstage/backend-common@0.19.0 + - @backstage/plugin-techdocs-node@1.7.2 + - @backstage/catalog-model@1.4.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + +## 1.4.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.0-next.2 + - @backstage/plugin-techdocs-node@1.7.2-next.2 + - @backstage/catalog-model@1.4.0-next.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.0-next.1 + - @backstage/plugin-techdocs-node@1.7.2-next.1 + - @backstage/catalog-model@1.4.0-next.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.6-next.0 + - @backstage/config@1.0.7 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/plugin-techdocs-node@1.7.2-next.0 + +## 1.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-techdocs-node@1.7.1 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5-next.1 + - @backstage/plugin-techdocs-node@1.7.1-next.1 + - @backstage/config@1.0.7 + +## 1.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5-next.0 + - @backstage/plugin-techdocs-node@1.7.1-next.0 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.1 + +### Patch Changes + +- b348420a804: Adding global-agent to enable the ability to publish through a proxy +- Updated dependencies + - @backstage/backend-common@0.18.4 + - @backstage/plugin-techdocs-node@1.7.0 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.1-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.3.0-next.0 + - @backstage/backend-common@0.18.4-next.2 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/plugin-techdocs-node@1.6.1-next.3 + +## 1.4.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.4-next.2 + - @backstage/catalog-model@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/plugin-techdocs-node@1.6.1-next.2 + +## 1.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.4-next.1 + - @backstage/catalog-model@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/plugin-techdocs-node@1.6.1-next.1 + +## 1.4.1-next.0 + +### Patch Changes + +- b348420a804: Adding global-agent to enable the ability to publish through a proxy +- Updated dependencies + - @backstage/backend-common@0.18.4-next.0 + - @backstage/config@1.0.7 + - @backstage/catalog-model@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/plugin-techdocs-node@1.6.1-next.0 + +## 1.4.0 + +### Minor Changes + +- 8e465ce52e2: Running `@techdocs/cli generate` with the `--verbose` flag will now print the mkdocs output. +- ea2bbef1b16: Added support for an HTTPS proxy for techdocs AWS S3 requests + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.6.0 + - @backstage/backend-common@0.18.3 + - @backstage/catalog-model@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.6.0-next.2 + - @backstage/backend-common@0.18.3-next.2 + - @backstage/config@1.0.7-next.0 + +## 1.4.0-next.1 + +### Minor Changes + +- 8e465ce52e2: Running `@techdocs/cli generate` with the `--verbose` flag will now print the mkdocs output. +- ea2bbef1b16: Added support for an HTTPS proxy for techdocs AWS S3 requests + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.6.0-next.1 + - @backstage/backend-common@0.18.3-next.1 + - @backstage/cli-common@0.1.12-next.0 + - @backstage/config@1.0.7-next.0 + - @backstage/catalog-model@1.2.1-next.1 + +## 1.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/plugin-techdocs-node@1.5.1-next.0 + +## 1.3.2 + +### Patch Changes + +- dd1e37649f: Deprecated getMkDocsYml in favor of getMkdocsYml (lowercase 'd') + +- dcacf94912: Fix proxying to mkdocs + + The domain localhost may point to both 127.0.0.1 and ::1, ipv4 and ipv6 + and when node tries to lookup localhost it might prefer ipv6 while mkdocs + is only listening on ipv4. This tells node-proxy to target the ipv4 address + instead of relying on localhost hostname lookup. + +- 339d9a5b5c: Added support for using a default `mkdocs.yml` configuration file when none is provided + +- 6e0b6a0d50: Fixed publish command missing awsBucketRootPath option. + Fixed publish command having the gcsBucketRootPath option misconfigured, previously returning a boolean vs a string. + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-techdocs-node@1.5.0 + - @backstage/catalog-model@1.2.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + +## 1.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2-next.2 + - @backstage/catalog-model@1.2.0-next.1 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/plugin-techdocs-node@1.4.6-next.2 + +## 1.3.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2-next.1 + - @backstage/catalog-model@1.1.6-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/plugin-techdocs-node@1.4.6-next.1 + +## 1.3.2-next.0 + +### Patch Changes + +- 6e0b6a0d50: Fixed publish command missing awsBucketRootPath option. + Fixed publish command having the gcsBucketRootPath option misconfigured, previously returning a boolean vs a string. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.4.6-next.0 + - @backstage/catalog-model@1.1.6-next.0 + - @backstage/backend-common@0.18.2-next.0 + +## 1.3.0 + +### Minor Changes + +- bc18c902a2: Add `--preview-app-bundle-path` and `--preview-app-port` options to the `serve` command enabling previewing with apps other than the provided one + +### Patch Changes + +- 9f2b786fc9: Provide context for logged errors. +- Updated dependencies + - @backstage/backend-common@0.18.0 + - @backstage/catalog-model@1.1.5 + - @backstage/config@1.0.6 + - @backstage/cli-common@0.1.11 + - @backstage/plugin-techdocs-node@1.4.4 + +## 1.3.0-next.2 + +### Minor Changes + +- bc18c902a2: Add `--preview-app-bundle-path` and `--preview-app-port` options to the `serve` command enabling previewing with apps other than the provided one + +### Patch Changes + +- 9f2b786fc9: Provide context for logged errors. +- Updated dependencies + - @backstage/backend-common@0.18.0-next.1 + - @backstage/plugin-techdocs-node@1.4.4-next.2 + - @backstage/catalog-model@1.1.5-next.1 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6-next.0 + +## 1.2.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.0-next.0 + - @backstage/config@1.0.6-next.0 + - @backstage/catalog-model@1.1.5-next.1 + - @backstage/cli-common@0.1.11 + - @backstage/plugin-techdocs-node@1.4.4-next.1 + +## 1.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.5-next.0 + - @backstage/backend-common@0.17.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.5 + - @backstage/plugin-techdocs-node@1.4.4-next.0 + +## 1.2.4 + +### Patch Changes + +- 8015ff1258: Tweaked wording to use inclusive terminology +- Updated dependencies + - @backstage/backend-common@0.17.0 + - @backstage/plugin-techdocs-node@1.4.3 + - @backstage/cli-common@0.1.11 + - @backstage/catalog-model@1.1.4 + - @backstage/config@1.0.5 + +## 1.2.4-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.17.0-next.3 + - @backstage/plugin-techdocs-node@1.4.3-next.3 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/cli-common@0.1.11-next.0 + - @backstage/config@1.0.5-next.1 + +## 1.2.4-next.2 + +### Patch Changes + +- 8015ff1258: Tweaked wording to use inclusive terminology +- Updated dependencies + - @backstage/backend-common@0.17.0-next.2 + - @backstage/cli-common@0.1.11-next.0 + - @backstage/plugin-techdocs-node@1.4.3-next.2 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/config@1.0.5-next.1 + +## 1.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.17.0-next.1 + - @backstage/plugin-techdocs-node@1.4.3-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/cli-common@0.1.10 + +## 1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-techdocs-node@1.4.3-next.0 + +## 1.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0 + - @backstage/plugin-techdocs-node@1.4.2 + - @backstage/catalog-model@1.1.3 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4 + +## 1.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-techdocs-node@1.4.2-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + +## 1.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.0 + - @backstage/plugin-techdocs-node@1.4.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + +## 1.2.2 + +### Patch Changes + +- 0b2a30dead: fixing techdocs-cli Docker client creation + + Docker client does not need to be created when --no-docker + option is provided. + + If you had DOCKER_CERT_PATH environment variable defined + the Docker client was looking for certificates + and breaking techdocs-cli generate command even with --no-docker + option. + +- Updated dependencies + - @backstage/catalog-model@1.1.2 + - @backstage/backend-common@0.15.2 + - @backstage/plugin-techdocs-node@1.4.1 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3 + +## 1.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.2-next.2 + - @backstage/plugin-techdocs-node@1.4.1-next.2 + - @backstage/catalog-model@1.1.2-next.2 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.2 + +## 1.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.2-next.1 + - @backstage/catalog-model@1.1.2-next.1 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.1 + - @backstage/plugin-techdocs-node@1.4.1-next.1 + +## 1.2.2-next.0 + +### Patch Changes + +- 0b2a30dead: fixing techdocs-cli Docker client creation + + Docker client does not need to be created when --no-docker + option is provided. + + If you had DOCKER_CERT_PATH environment variable defined + the Docker client was looking for certificates + and breaking techdocs-cli generate command even with --no-docker + option. + +- Updated dependencies + - @backstage/catalog-model@1.1.2-next.0 + - @backstage/plugin-techdocs-node@1.4.1-next.0 + - @backstage/backend-common@0.15.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.0 + +## 1.2.1 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/backend-common@0.15.1 + - @backstage/plugin-techdocs-node@1.4.0 + - @backstage/catalog-model@1.1.1 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.2 + +## 1.2.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-techdocs-node@1.4.0-next.2 + +## 1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.4.0-next.1 + - @backstage/backend-common@0.15.1-next.2 + +## 1.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.1-next.0 + - @backstage/plugin-techdocs-node@1.3.1-next.0 + +## 1.2.0 + +### Minor Changes + +- 855952db53: Added CLI option `--docker-option` to allow passing additional options to the `docker run` command executed my `serve` and `serve:mkdocs`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-techdocs-node@1.3.0 + +## 1.2.0-next.2 + +### Minor Changes + +- 855952db53: Added CLI option `--docker-option` to allow passing additional options to the `docker run` command executed my `serve` and `serve:mkdocs`. + +## 1.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/plugin-techdocs-node@1.3.0-next.1 + +## 1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-techdocs-node@1.2.1-next.0 + +## 1.1.3 + +### Patch Changes + +- a5d73da942: Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. +- 14ce0d9347: Fixed a bug that prevented docker images from being pulled by default when generating TechDocs. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.2.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + +## 1.1.3-next.1 + +### Patch Changes + +- a5d73da942: Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.2.0-next.1 + - @backstage/catalog-model@1.1.0-next.1 + - @backstage/backend-common@0.14.1-next.1 + +## 1.1.3-next.0 + +### Patch Changes + +- 14ce0d9347: Fixed a bug that prevented docker images from being pulled by default when generating TechDocs. +- Updated dependencies + - @backstage/backend-common@0.14.1-next.0 + - @backstage/catalog-model@1.1.0-next.0 + - @backstage/plugin-techdocs-node@1.1.3-next.0 + +## 1.1.2 + +### Patch Changes + +- f96e98f4cd: Updated dependency `cypress` to `^10.0.0`. +- bff65e6958: Updated sidebar-related logic to use `` + `useSidebarPinState()` and/or `` + `useSidebarOpenState()` from `@backstage/core-components`. +- Updated dependencies + - @backstage/backend-common@0.14.0 + - @backstage/plugin-techdocs-node@1.1.2 + - @backstage/catalog-model@1.0.3 + +## 1.1.2-next.2 + +### Patch Changes + +- f96e98f4cd: Updated dependency `cypress` to `^10.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.0-next.2 + - @backstage/plugin-techdocs-node@1.1.2-next.2 + +## 1.1.2-next.1 + +### Patch Changes + +- bff65e6958: Updated sidebar-related logic to use `` + `useSidebarPinState()` and/or `` + `useSidebarOpenState()` from `@backstage/core-components`. +- Updated dependencies + - @backstage/backend-common@0.13.6-next.1 + - @backstage/catalog-model@1.0.3-next.0 + - @backstage/plugin-techdocs-node@1.1.2-next.1 + +## 1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.13.6-next.0 + - @backstage/plugin-techdocs-node@1.1.2-next.0 + +## 1.1.1 + +### Patch Changes + +- 344ea56acc: Bump `commander` to version 9.1.0 +- 52fddad92d: The TechDocs CLI's embedded app now imports all API refs from the `@backstage/plugin-techdocs-react` package. +- c14e78a367: Update `techdocs-cli serve`'s `proxyEndpoint` to match the base URL of the embedded techdocs app. +- Updated dependencies + - @backstage/backend-common@0.13.3 + - @backstage/cli-common@0.1.9 + - @backstage/config@1.0.1 + - @backstage/plugin-techdocs-node@1.1.1 + - @backstage/catalog-model@1.0.2 + +## 1.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.13.3-next.2 + - @backstage/cli-common@0.1.9-next.0 + - @backstage/config@1.0.1-next.0 + - @backstage/catalog-model@1.0.2-next.0 + - @backstage/plugin-techdocs-node@1.1.1-next.1 + +## 1.1.1-next.1 + +### Patch Changes + +- 52fddad92d: The TechDocs CLI's embedded app now imports all API refs from the `@backstage/plugin-techdocs-react` package. +- Updated dependencies + - @backstage/backend-common@0.13.3-next.1 + +## 1.1.1-next.0 + +### Patch Changes + +- 344ea56acc: Bump `commander` to version 9.1.0 +- Updated dependencies + - @backstage/backend-common@0.13.3-next.0 + - @backstage/plugin-techdocs-node@1.1.1-next.0 + +## 1.1.0 + +### Minor Changes + +- 733187987b: Removed an undocumented, broken behavior where `README.md` files would be copied to `index.md` if it did not exist, leading to broken links in the TechDocs UI. + + **WARNING**: If you notice 404s in TechDocs after updating, check to make sure that all markdown files referenced in your `mkdocs.yml`s' `nav` sections exist. The following flag may be passed to the `generate` command to temporarily revert to the broken behavior. + + ```sh + techdocs-cli generate --legacyCopyReadmeMdToIndexMd + ``` + +### Patch Changes + +- 230ad0826f: Bump to using `@types/node` v16 +- eb470ea54c: Adds a new flag to override the entrypoint when using a custom docker image. It could be used to reuse existing images with different entrypoints. +- Updated dependencies + - @backstage/catalog-model@1.0.1 + - @backstage/backend-common@0.13.2 + - @backstage/plugin-techdocs-node@1.1.0 + +## 1.1.0-next.1 + +### Minor Changes + +- bcf1a2496c: BREAKING: The default Techdocs behavior will no longer attempt to copy `docs/README.md` or `README.md` to `docs/index.md` (if not found). To retain this behavior in your instance, you can set the following config in your `app-config.yaml`: + + ```yaml + techdocs: + generator: + mkdocs: + legacyCopyReadmeMdToIndexMd: true + ``` + +### Patch Changes + +- 230ad0826f: Bump to using `@types/node` v16 +- eb470ea54c: Adds a new flag to override the entrypoint when using a custom docker image. It could be used to reuse existing images with different entrypoints. +- Updated dependencies + - @backstage/backend-common@0.13.2-next.2 + - @backstage/plugin-techdocs-node@1.1.0-next.2 + +## 1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.0.1-next.0 + - @backstage/backend-common@0.13.2-next.0 + - @backstage/plugin-techdocs-node@1.0.1-next.0 + +## 1.0.0 + +### Major Changes + +- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.13.1 + - @backstage/catalog-model@1.0.0 + - @backstage/config@1.0.0 + - @backstage/plugin-techdocs-node@1.0.0 + +## 0.8.17 + +### Patch Changes + +- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 +- 91bf1e6c1a: Use `@backstage/plugin-techdocs-node` package instead of `@backstage/techdocs-common`. +- Updated dependencies + - @backstage/backend-common@0.13.0 + - @backstage/plugin-techdocs-node@0.11.12 + - @backstage/catalog-model@0.13.0 + +## 0.8.17-next.0 + +### Patch Changes + +- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 +- 91bf1e6c1a: Use `@backstage/plugin-techdocs-node` package instead of `@backstage/techdocs-common`. +- Updated dependencies + - @backstage/backend-common@0.13.0-next.0 + - @backstage/plugin-techdocs-node@0.11.12-next.0 + - @backstage/catalog-model@0.13.0-next.0 + +## 0.8.16 + +### Patch Changes + +- 853efd42bd: Bump `@backstage/techdocs-common` to `0.11.10` to use `spotify/techdocs:v0.3.7` which upgrades `mkdocs-theme` as a dependency of `mkdocs-techdocs-core`. +- Updated dependencies + - @backstage/catalog-model@0.12.0 + - @backstage/backend-common@0.12.0 + - @backstage/techdocs-common@0.11.11 + +## 0.8.15 + +### Patch Changes + +- ed78516480: chore(deps-dev): bump `cypress` from 7.3.0 to 9.5.0 +- 209fd128e6: Updated usage of `github:` location types in docs to use `url:` instead. +- 61ff215e08: - Adds `cypress` and `cypress-plugin-snapshots` as dependencies for integration and visual regression tests. + - Updates README documentation with instructions for how to run tests. + - Clarifies output text for prepack script. +- Updated dependencies + - @backstage/backend-common@0.11.0 + - @backstage/catalog-model@0.11.0 + - @backstage/techdocs-common@0.11.10 + +## 0.8.14 + +### Patch Changes + +- c77c5c7eb6: Added `backstage.role` to `package.json` +- Updated dependencies + - @backstage/backend-common@0.10.8 + - @backstage/catalog-model@0.10.0 + - @backstage/cli-common@0.1.7 + - @backstage/config@0.1.14 + - @backstage/techdocs-common@0.11.8 + +## 0.8.13 + +### Patch Changes + +- b70c186194: Updated the HTTP server to allow for simplification of the development of the CLI itself. +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/techdocs-common@0.11.7 + +## 0.8.13-next.0 + +### Patch Changes + +- b70c186194: Updated the HTTP server to allow for simplification of the development of the CLI itself. +- Updated dependencies + - @backstage/backend-common@0.10.7-next.0 + - @backstage/techdocs-common@0.11.7-next.0 + +## 0.8.12 + +### Patch Changes + +- 14472509a3: Use a local file dependency for techdocs-cli-embedded-app, to ensure that it's always pulled out of the workspace +- Updated dependencies + - @backstage/backend-common@0.10.6 + - @backstage/techdocs-common@0.11.6 + +## 0.8.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.6-next.0 + - @backstage/techdocs-common@0.11.6-next.0 + +## 0.8.12-next.0 + +### Patch Changes + +- 14472509a3: Use a local file dependency for techdocs-cli-embedded-app, to ensure that it's always pulled out of the workspace + +## 0.8.11 + +### Patch Changes + +- 10086f5873: Bumped `react-dev-utils` from `^12.0.0-next.47` to `^12.0.0-next.60`. +- Updated dependencies + - @backstage/techdocs-common@0.11.5 + - @backstage/backend-common@0.10.5 + +## 0.8.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.4-next.0 + - @backstage/config@0.1.13-next.0 + - @backstage/techdocs-common@0.11.4-next.0 + - @backstage/catalog-model@0.9.10-next.0 + +## 0.8.10 + +### Patch Changes + +- 8fbc988bfc: remove internal and inline CSS from index.html +- Updated dependencies + - @backstage/techdocs-common@0.11.2 + - @backstage/backend-common@0.10.1 + +## 0.8.9 + +### Patch Changes + +- 5fdc8df0e8: The `index.html` template was updated to use the new `config` global. +- Updated dependencies + - @backstage/backend-common@0.10.0 + - @backstage/techdocs-common@0.11.1 + +## 0.8.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.9.13 + - @backstage/techdocs-common@0.11.0 + +## 0.8.7 + +### Patch Changes + +- e7230ef814: Bump react-dev-utils to v12 +- Updated dependencies + - @backstage/backend-common@0.9.12 + +## 0.8.6 + +### Patch Changes + +- e21e3c6102: Bumping minimum requirements for `dockerode` and `testcontainers` +- 1578ad341b: Add support for specifying bucketRootPath for AWS and GCS publishers +- f2694e3750: Adds ability to use encrypted S3 buckets by utilizing the SSE option in the AWS SDK +- Updated dependencies + - @backstage/catalog-model@0.9.7 + - @backstage/backend-common@0.9.10 + - @backstage/techdocs-common@0.10.7 + +## 0.8.5 + +### Patch Changes + +- Reunified the [techdocs-cli](https://github.com/backstage/techdocs-cli) monorepo code back into the main [backstage](https://github.com/backstage/backstage) repo + + See [7288](https://github.com/backstage/backstage/issues/7288)). The changes include some internal refactoring that do not affect functionality beyond the local development setup. + +## 0.8.4 + +### Patch Changes + +- 8333394: The [change](https://github.com/backstage/techdocs-cli/commit/b25014cec313d46ce1c9b4f324cc09047a00fc1f) updated the `@backstage/techdocs-common` from version `0.9.0` to `0.10.2` and one of the intermediate versions, the [0.10.0](https://github.com/backstage/backstage/blob/cac4afb95fdbd130a66e53a1b0430a1e62787a7f/packages/techdocs-common/CHANGELOG.md#patch-changes-2), introduced the use of search in context that requires an implementation for the Search API. + + Created a custom techdocs page to disable search in the Reader component, preventing it from using the Search API, as we don't want to provide search in preview mode. + +## 0.8.3 + +### Patch Changes + +- edbb988: Upgrades the techdocs common page to the latest version 0.10.2. + + See [@backstage/techdocs-common changelog](https://github.com/backstage/backstage/blob/cac4afb95fdbd130a66e53a1b0430a1e62787a7f/packages/techdocs-common/CHANGELOG.md#L3). + +- db4ebfc: Add an `etag` flag to the `generate` command that is stored in the `techdocs_metadata.json` file. + +## 0.8.2 + +### Patch Changes + +- 8fc7384: Allow to execute techdocs-cli serve using docker techdocs-container on Windows + +## 0.8.1 + +### Patch Changes + +- 0187424: Separate build and publish release steps + +## 0.8.0 + +### Minor Changes + +- c6f437a: OpenStack Swift configuration changed due to OSS SDK Client change in @backstage/techdocs-common, it was a breaking change. + PR Reference: + +### Patch Changes + +- 05f0409: Merge Jobs for Release Pull Requests and Package Publishes + +## 0.7.0 + +### Minor Changes + +- 9d1f8d8: The `techdocs-cli publish` command will now publish TechDocs content to remote + storage using the lowercase'd entity triplet as the storage path. This is in + line with the beta release of the TechDocs plugin (`v0.11.0`). + + If you have been running `techdocs-cli` prior to this version, you will need to + follow this [migration guide](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-migrate-from-techdocs-alpha-to-beta). + +## 0.6.2 + +### Patch Changes + +- f1bcf1a: Changelog (from v0.6.1 to v0.6.2) + + #### :bug: Bug Fix + + - `techdocs-cli` + - [#105](https://github.com/backstage/techdocs-cli/pull/105) Add azureAccountKey parameter back to the publish command ([@emmaindal](https://github.com/emmaindal)) + + #### :house: Internal + + - `techdocs-cli-embedded-app` + - [#122](https://github.com/backstage/techdocs-cli/pull/122) chore(deps-dev): bump @types/node from 12.20.20 to 16.7.1 in /packages/techdocs-cli-embedded-app ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - [#120](https://github.com/backstage/techdocs-cli/pull/120) chore(deps-dev): bump @types/react-dom from 16.9.14 to 17.0.9 in /packages/techdocs-cli-embedded-app ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - [#119](https://github.com/backstage/techdocs-cli/pull/119) chore(deps-dev): bump @testing-library/user-event from 12.8.3 to 13.2.1 in /packages/techdocs-cli-embedded-app ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - [#118](https://github.com/backstage/techdocs-cli/pull/118) chore(deps-dev): bump @testing-library/react from 10.4.9 to 12.0.0 ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - Other + - [#117](https://github.com/backstage/techdocs-cli/pull/117) chore(deps): bump @backstage/plugin-catalog from 0.6.11 to 0.6.12 ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - [#124](https://github.com/backstage/techdocs-cli/pull/124) Update release process docs ([@emmaindal](https://github.com/emmaindal)) + - [#116](https://github.com/backstage/techdocs-cli/pull/116) ignore dependabot branches for project board workflow ([@emmaindal](https://github.com/emmaindal)) + - [#106](https://github.com/backstage/techdocs-cli/pull/106) Configure dependabot for all packages ([@emmaindal](https://github.com/emmaindal)) + - [#102](https://github.com/backstage/techdocs-cli/pull/102) readme: add information about running techdocs-common locally ([@vcapretz](https://github.com/vcapretz)) + - [#103](https://github.com/backstage/techdocs-cli/pull/103) Introduce changesets and improve the publish workflow ([@minkimcello](https://github.com/minkimcello)) + - [#101](https://github.com/backstage/techdocs-cli/pull/101) update yarn lockfile to get rid of old version of node-forge ([@emmaindal](https://github.com/emmaindal)) + + #### Committers: 3 + + Thank you for contributing ❤️ + + - `Emma Indal` ([@emmaindal](https://github.com/emmaindal)) + - `Min Kim` ([@minkimcello](https://github.com/minkimcello)) + - `Vitor Capretz` ([@vcapretz](https://github.com/vcapretz)) + +## @backstage/plugin-techdocs@1.15.3-next.0 + +# @backstage/plugin-techdocs + +## 1.15.2-next.0 + +### Patch Changes + +- a4d4a70: Fixed an issue where the entire TechDocs page would re-render when navigating between pages within the same entity's documentation. +- Updated dependencies + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-auth-react@0.1.21-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## 1.15.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/integration@1.18.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/plugin-search-react@1.9.5 + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-auth-react@0.1.20 + - @backstage/plugin-search-common@1.2.20 + +## 1.15.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/plugin-search-react@1.9.5-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + +## 1.15.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-auth-react@0.1.20-next.1 + - @backstage/plugin-search-common@1.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## 1.15.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-auth-react@0.1.20-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## 1.15.0 + +### Minor Changes + +- a0b604c: Adding redirect handling for TechDocs URLs that reference entities that now reference an external entity for TechDocs. Including tests and documentation. + +### Patch Changes + +- 313cec7: Updated dependency `dompurify` to `^3.2.4`. +- 8d18d23: TechDocs page titles have been improved, especially for deeply nested pages. +- 1dfee19: Reverts a change in CSS layout that shifted the content of the Techdocs too far to the left. +- 4ce5831: Support Techdocs redirect with dompurify 3.2.6+ +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-auth-react@0.1.19 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/integration@1.18.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-search-react@1.9.4 + - @backstage/integration-react@1.2.10 + +## 1.14.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-react@0.1.19-next.1 + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-compat-api@0.5.2-next.2 + +## 1.14.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/plugin-auth-react@0.1.19-next.0 + +## 1.14.2-next.0 + +### Patch Changes + +- 1dfee19: Reverts a change in CSS layout that shifted the content of the Techdocs too far to the left. +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.2 + +## 1.14.0 + +### Minor Changes + +- cb0541f: Adds `additionalAllowedURIProtocols` to sanitizer config + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- f231c2b: Fixes CSS to adjust based on whether or not the global Backstage sidebar is on the page. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-techdocs-react@1.3.2 + +## 1.14.0-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## 1.14.0-next.1 + +### Minor Changes + +- cb0541f: Adds `additionalAllowedURIProtocols` to sanitizer config + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## 1.13.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-react@1.9.2 + +## 1.13.2 + +### Patch Changes + +- 1debf7f: Fixed an issue causing TechDocs to not properly handle initial redirect. +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + - @backstage/theme@0.6.7 + - @backstage/integration-react@1.2.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-auth-react@0.1.17 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-react@1.3.1 + +## 1.13.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-auth-react@0.1.17-next.1 + +## 1.13.2-next.0 + +### Patch Changes + +- 1debf7f: Fixed an issue causing TechDocs to not properly handle initial redirect. +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1 + +## 1.13.0 + +### Minor Changes + +- 3c59ece: **New Frontend System Only:** + The `TechDocs` plugin is now responsible for providing an entity icon link extension to read documentation from the catalog entity page. +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-search-react@1.9.1 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/theme@0.6.6 + - @backstage/plugin-search-common@1.2.18 + +## 1.13.0-next.2 + +### Minor Changes + +- 3c59ece: **New Frontend System Only:** + The `TechDocs` plugin is now responsible for providing an entity icon link extension to read documentation from the catalog entity page. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/theme@0.6.6 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + +## 1.13.0-next.1 + +### Patch Changes + +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration@1.17.0 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## 1.13.0-next.0 + +### Minor Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/integration-react@1.2.7 + +## 1.12.6 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 7d445da: Update keyboard focus on when clicking hash links. This fixes the issue where the "skip to content" link rendered by Material MkDocs isn't focused when used. +- 72d019d: Removed various typos +- 2ffd273: Add hover and focus styling to the "copy to clipboard" button within codeblocks in techdocs. Also added an aria-label to the button for accessibility. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/integration@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.6-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0-next.3 + - @backstage/plugin-search-react@1.9.0-next.2 + - @backstage/core-compat-api@0.4.2-next.3 + - @backstage/core-components@0.17.2-next.1 + - @backstage/core-plugin-api@1.10.7-next.0 + - @backstage/plugin-catalog-react@1.18.0-next.3 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.2-next.1 + - @backstage/integration-react@1.2.7-next.3 + - @backstage/theme@0.6.6-next.0 + - @backstage/plugin-auth-react@0.1.15-next.1 + - @backstage/plugin-search-common@1.2.18-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.17-next.1 + +## 1.12.6-next.2 + +### Patch Changes + +- 7d445da: Update keyboard focus on when clicking hash links. This fixes the issue where the "skip to content" link rendered by Material MkDocs isn't focused when used. +- 2ffd273: Add hover and focus styling to the "copy to clipboard" button within codeblocks in techdocs. Also added an aria-label to the button for accessibility. +- Updated dependencies + - @backstage/integration@1.17.0-next.2 + - @backstage/core-plugin-api@1.10.7-next.0 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.2-next.2 + - @backstage/core-components@0.17.2-next.1 + - @backstage/frontend-plugin-api@0.10.2-next.1 + - @backstage/integration-react@1.2.7-next.2 + - @backstage/plugin-auth-react@0.1.15-next.1 + - @backstage/plugin-catalog-react@1.18.0-next.2 + - @backstage/plugin-search-react@1.9.0-next.1 + - @backstage/plugin-techdocs-react@1.2.17-next.1 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6-next.0 + - @backstage/plugin-search-common@1.2.18-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.6-next.1 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/theme@0.6.6-next.0 + - @backstage/core-components@0.17.2-next.0 + - @backstage/frontend-plugin-api@0.10.2-next.0 + - @backstage/core-compat-api@0.4.2-next.1 + - @backstage/integration@1.16.4-next.1 + - @backstage/plugin-search-react@1.9.0-next.0 + - @backstage/plugin-catalog-react@1.18.0-next.1 + - @backstage/plugin-techdocs-react@1.2.17-next.0 + - @backstage/plugin-auth-react@0.1.15-next.0 + - @backstage/integration-react@1.2.7-next.1 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.6 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.18-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.16.4-next.0 + - @backstage/core-compat-api@0.4.2-next.0 + - @backstage/plugin-catalog-react@1.18.0-next.0 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/integration-react@1.2.7-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-components@0.17.1 + - @backstage/core-plugin-api@1.10.6 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.1 + - @backstage/theme@0.6.5 + - @backstage/plugin-auth-react@0.1.14 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.8 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.16 + +## 1.12.5 + +### Patch Changes + +- a47fd39: Removes instances of default React imports, a necessary update for the upcoming React 19 migration. + + + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.16 + - @backstage/plugin-catalog-react@1.17.0 + - @backstage/frontend-plugin-api@0.10.1 + - @backstage/integration-react@1.2.6 + - @backstage/core-compat-api@0.4.1 + - @backstage/core-components@0.17.1 + - @backstage/core-plugin-api@1.10.6 + - @backstage/plugin-search-react@1.8.8 + - @backstage/plugin-auth-react@0.1.14 + - @backstage/theme@0.6.5 + - @backstage/integration@1.16.3 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.5-next.2 + +### Patch Changes + +- a47fd39: Removes instances of default React imports, a necessary update for the upcoming React 19 migration. + + + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.1-next.1 + - @backstage/integration-react@1.2.6-next.1 + - @backstage/core-compat-api@0.4.1-next.2 + - @backstage/core-components@0.17.1-next.1 + - @backstage/core-plugin-api@1.10.6-next.0 + - @backstage/plugin-techdocs-react@1.2.16-next.1 + - @backstage/plugin-catalog-react@1.17.0-next.2 + - @backstage/plugin-search-react@1.8.8-next.1 + - @backstage/plugin-auth-react@0.1.14-next.1 + - @backstage/theme@0.6.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.3-next.0 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.16-next.0 + - @backstage/core-components@0.17.1-next.0 + - @backstage/integration-react@1.2.6-next.0 + - @backstage/integration@1.16.3-next.0 + - @backstage/frontend-plugin-api@0.10.1-next.0 + - @backstage/plugin-auth-react@0.1.14-next.0 + - @backstage/plugin-catalog-react@1.16.1-next.1 + - @backstage/plugin-search-react@1.8.8-next.0 + - @backstage/core-compat-api@0.4.1-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.5 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.4 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.16.1-next.0 + - @backstage/core-compat-api@0.4.1-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-components@0.17.0 + - @backstage/core-plugin-api@1.10.5 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.0 + - @backstage/integration@1.16.2 + - @backstage/integration-react@1.2.5 + - @backstage/theme@0.6.4 + - @backstage/plugin-auth-react@0.1.13 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.7 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.15 + +## 1.12.4 + +### Patch Changes + +- fffe3c0: Fixed double scrollbar issue that would appear on the Entity TechDocs view page that would stop the page from full scrolling to the top when navigating to a new page +- 065e6b9: Excludes SVG styling from sanitization +- b5a8208: Added `TechDocsAddonsBlueprint` extension to allow adding of techdocs addons. +- ed1cb3e: Adds the page name of techdocs to the document's title. +- fe4abb8: Updates logic to check for SVG sources when inlining them. +- Updated dependencies + - @backstage/core-components@0.17.0 + - @backstage/core-plugin-api@1.10.5 + - @backstage/integration@1.16.2 + - @backstage/plugin-search-react@1.8.7 + - @backstage/frontend-plugin-api@0.10.0 + - @backstage/plugin-catalog-react@1.16.0 + - @backstage/core-compat-api@0.4.0 + - @backstage/plugin-techdocs-react@1.2.15 + - @backstage/integration-react@1.2.5 + - @backstage/plugin-auth-react@0.1.13 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.4 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.0-next.2 + - @backstage/plugin-catalog-react@1.16.0-next.2 + - @backstage/core-compat-api@0.4.0-next.2 + - @backstage/core-components@0.16.5-next.1 + - @backstage/integration@1.16.2-next.0 + - @backstage/plugin-search-react@1.8.7-next.2 + - @backstage/plugin-techdocs-react@1.2.15-next.2 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.4 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.5-next.0 + - @backstage/theme@0.6.4 + - @backstage/plugin-auth-react@0.1.13-next.1 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.4-next.1 + +### Patch Changes + +- fffe3c0: Fixed double scrollbar issue that would appear on the Entity TechDocs view page that would stop the page from full scrolling to the top when navigating to a new page +- Updated dependencies + - @backstage/core-components@0.16.5-next.0 + - @backstage/plugin-catalog-react@1.16.0-next.1 + - @backstage/core-compat-api@0.3.7-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.4 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.9.6-next.1 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.4 + - @backstage/theme@0.6.4 + - @backstage/plugin-auth-react@0.1.13-next.0 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.7-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.15-next.1 + +## 1.12.4-next.0 + +### Patch Changes + +- 065e6b9: Excludes svg styling from sanitization +- b5a8208: Added `TechDocsAddonsBlueprint` extension to allow adding of techdocs addons. +- ed1cb3e: Adds the page name of techdoc to the document's title. +- fe4abb8: Updates logic to check for SVG sources when inlining svgs. +- Updated dependencies + - @backstage/plugin-search-react@1.8.7-next.0 + - @backstage/plugin-catalog-react@1.16.0-next.0 + - @backstage/plugin-techdocs-react@1.2.15-next.0 + - @backstage/frontend-plugin-api@0.9.6-next.0 + - @backstage/core-compat-api@0.3.7-next.0 + - @backstage/integration-react@1.2.4 + +## 1.12.3 + +### Patch Changes + +- eb3d91a: Use the custom error page if provided for displaying errors instead of the default error page + +- 524f0af: Add missing route ref to the `/alpha` entity content extension. + +- f4be934: Changed the base URL in addLinkClickListener from window.location.origin to app.baseUrl for improved path handling. This fixes an issue where Backstage, when running on a subpath, was unable to handle non-Backstage URLs of the same origin correctly. + +- 1f40e6b: Add optional props to `TechDocCustomHome` to allow for more flexibility: + + ```tsx + import { TechDocsCustomHome } from '@backstage/plugin-techdocs'; + //... + + const options = { emptyRowsWhenPaging: false }; + const linkDestination = (entity: Entity): string | undefined => { + return entity.metadata.annotations?.['external-docs']; + }; + const techDocsTabsConfig = [ + { + label: 'Recommended Documentation', + panels: [ + { + title: 'Golden Path', + description: 'Documentation about standards to follow', + panelType: 'DocsCardGrid', + panelProps: { CustomHeader: () => }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('golden-path') ?? false, + }, + { + title: 'Recommended', + description: 'Useful documentation', + panelType: 'InfoCardGrid', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ], + }, + { + label: 'Browse All', + panels: [ + { + description: 'Browse all docs', + filterPredicate: filterEntity, + panelType: 'TechDocsIndexPage', + title: 'All', + panelProps: { PageWrapper: React.Fragment, CustomHeader: React.Fragment, options: options }, + }, + ], + }, + ]; + + const AppRoutes = () => { + + ) => ({children})} + /> + } + /> + ; + }; + ``` + + Add new Grid option called `InfoCardGrid` which is a more customizable card option for the Docs grid. + + ```tsx + entity.metadata['external-docs']} + /> + ``` + + Expose existing `CustomDocsPanel` so that it can be used independently if desired. + + ```tsx + const panels: PanelConfig[] = [ + { + description: '', + filterPredicate: entity => {}, + panelType: 'InfoCardGrid', + title: 'Standards', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + }, + { + description: '', + filterPredicate: entity => {}, + panelType: 'DocsCardGrid', + title: 'Contribute', + }, + ]; + { + panels.map((config, index) => ( + + )); + } + ``` + +- 58ec9e7: Removed older versions of React packages as a preparatory step for upgrading to React 19. This commit does not introduce any functional changes, but removes dependencies on previous React versions, allowing for a cleaner upgrade path in subsequent commits. + +- Updated dependencies + - @backstage/plugin-search-react@1.8.6 + - @backstage/core-components@0.16.4 + - @backstage/plugin-catalog-react@1.15.2 + - @backstage/frontend-plugin-api@0.9.5 + - @backstage/integration-react@1.2.4 + - @backstage/core-compat-api@0.3.6 + - @backstage/core-plugin-api@1.10.4 + - @backstage/plugin-techdocs-react@1.2.14 + - @backstage/plugin-auth-react@0.1.12 + - @backstage/theme@0.6.4 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.3 + - @backstage/core-compat-api@0.3.6-next.3 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-components@0.16.4-next.1 + - @backstage/core-plugin-api@1.10.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.4-next.0 + - @backstage/theme@0.6.4-next.0 + - @backstage/plugin-auth-react@0.1.12-next.1 + - @backstage/plugin-catalog-react@1.15.2-next.3 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.6-next.3 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.14-next.1 + +## 1.12.3-next.2 + +### Patch Changes + +- eb3d91a: Use the custom error page if provided for displaying errors instead of the default error page +- Updated dependencies + - @backstage/core-components@0.16.4-next.1 + - @backstage/plugin-catalog-react@1.15.2-next.2 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.3.6-next.2 + - @backstage/core-plugin-api@1.10.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.9.5-next.2 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.4-next.0 + - @backstage/theme@0.6.4-next.0 + - @backstage/plugin-auth-react@0.1.12-next.1 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.6-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.14-next.1 + +## 1.12.2-next.1 + +### Patch Changes + +- 524f0af: Add missing route ref to the `/alpha` entity content extension. +- 58ec9e7: Removed older versions of React packages as a preparatory step for upgrading to React 19. This commit does not introduce any functional changes, but removes dependencies on previous React versions, allowing for a cleaner upgrade path in subsequent commits. +- Updated dependencies + - @backstage/core-components@0.16.4-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.1 + - @backstage/integration-react@1.2.4-next.0 + - @backstage/core-compat-api@0.3.6-next.1 + - @backstage/core-plugin-api@1.10.4-next.0 + - @backstage/plugin-techdocs-react@1.2.14-next.0 + - @backstage/plugin-catalog-react@1.15.2-next.1 + - @backstage/plugin-search-react@1.8.6-next.1 + - @backstage/plugin-auth-react@0.1.12-next.0 + - @backstage/theme@0.6.4-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.2-next.0 + +### Patch Changes + +- f4be934: Changed the base URL in addLinkClickListener from window.location.origin to app.baseUrl for improved path handling. This fixes an issue where Backstage, when running on a subpath, was unable to handle non-Backstage URLs of the same origin correctly. + +- 1f40e6b: Add optional props to `TechDocCustomHome` to allow for more flexibility: + + ```tsx + import { TechDocsCustomHome } from '@backstage/plugin-techdocs'; + //... + + const options = { emptyRowsWhenPaging: false }; + const linkDestination = (entity: Entity): string | undefined => { + return entity.metadata.annotations?.['external-docs']; + }; + const techDocsTabsConfig = [ + { + label: 'Recommended Documentation', + panels: [ + { + title: 'Golden Path', + description: 'Documentation about standards to follow', + panelType: 'DocsCardGrid', + panelProps: { CustomHeader: () => }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('golden-path') ?? false, + }, + { + title: 'Recommended', + description: 'Useful documentation', + panelType: 'InfoCardGrid', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ], + }, + { + label: 'Browse All', + panels: [ + { + description: 'Browse all docs', + filterPredicate: filterEntity, + panelType: 'TechDocsIndexPage', + title: 'All', + panelProps: { PageWrapper: React.Fragment, CustomHeader: React.Fragment, options: options }, + }, + ], + }, + ]; + + const AppRoutes = () => { + + ) => ({children})} + /> + } + /> + ; + }; + ``` + + Add new Grid option called `InfoCardGrid` which is a more customizable card option for the Docs grid. + + ```tsx + entity.metadata['external-docs']} + /> + ``` + + Expose existing `CustomDocsPanel` so that it can be used independently if desired. + + ```tsx + const panels: PanelConfig[] = [ + { + description: '', + filterPredicate: entity => {}, + panelType: 'InfoCardGrid', + title: 'Standards', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + }, + { + description: '', + filterPredicate: entity => {}, + panelType: 'DocsCardGrid', + title: 'Contribute', + }, + ]; + { + panels.map((config, index) => ( + + )); + } + ``` + +- Updated dependencies + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.13 + +## 1.12.1 + +### Patch Changes + +- 3710b35: Allow passing down `withSearch` prop to `EntityTechdocsContent` component since it was `true` by default, now user can use the `EntityTechdocsContent` component _without_ showing the search field on top of the content. +- Updated dependencies + - @backstage/plugin-catalog-react@1.15.1 + - @backstage/frontend-plugin-api@0.9.4 + - @backstage/core-plugin-api@1.10.3 + - @backstage/core-components@0.16.3 + - @backstage/integration@1.16.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.3.5 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.5 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.13 + +## 1.12.1-next.1 + +### Patch Changes + +- 3710b35: Allow passing down `withSearch` prop to `EntityTechdocsContent` component since it was `true` by default, now user can use the `EntityTechdocsContent` component _without_ showing the search field on top of the content. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.4-next.0 + - @backstage/core-plugin-api@1.10.3-next.0 + - @backstage/core-compat-api@0.3.5-next.0 + - @backstage/plugin-catalog-react@1.15.1-next.1 + - @backstage/plugin-search-react@1.8.5-next.0 + - @backstage/core-components@0.16.3-next.0 + - @backstage/integration-react@1.2.3-next.0 + - @backstage/plugin-auth-react@0.1.11-next.0 + - @backstage/plugin-techdocs-react@1.2.13-next.0 + - @backstage/catalog-model@1.7.3-next.0 + - @backstage/config@1.3.2-next.0 + - @backstage/errors@1.2.7-next.0 + - @backstage/plugin-search-common@1.2.17-next.0 + - @backstage/integration@1.16.1-next.0 + - @backstage/theme@0.6.3 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.15.1-next.0 + - @backstage/integration-react@1.2.2 + - @backstage/core-compat-api@0.3.4 + +## 1.12.0 + +### Minor Changes + +- e153ca6: Add pagination support to TechDocs Index Page and make it the default + +### Patch Changes + +- 7d8777d: Added support for the Search bar in docs residing in the entity page tab, and not only the global "/docs" page. +- Updated dependencies + - @backstage/plugin-catalog-react@1.15.0 + - @backstage/integration@1.16.0 + - @backstage/plugin-search-react@1.8.4 + - @backstage/core-compat-api@0.3.4 + - @backstage/frontend-plugin-api@0.9.3 + - @backstage/theme@0.6.3 + - @backstage/core-components@0.16.2 + - @backstage/errors@1.2.6 + - @backstage/catalog-model@1.7.2 + - @backstage/config@1.3.1 + - @backstage/core-plugin-api@1.10.2 + - @backstage/integration-react@1.2.2 + - @backstage/plugin-auth-react@0.1.10 + - @backstage/plugin-search-common@1.2.16 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.12 + +## 1.11.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.3.4-next.2 + - @backstage/plugin-catalog-react@1.14.3-next.2 + - @backstage/errors@1.2.6-next.0 + - @backstage/catalog-model@1.7.2-next.0 + - @backstage/config@1.3.1-next.0 + - @backstage/core-components@0.16.2-next.2 + - @backstage/core-plugin-api@1.10.2-next.0 + - @backstage/frontend-plugin-api@0.9.3-next.2 + - @backstage/integration@1.16.0-next.1 + - @backstage/integration-react@1.2.2-next.1 + - @backstage/theme@0.6.3-next.0 + - @backstage/plugin-auth-react@0.1.10-next.2 + - @backstage/plugin-search-common@1.2.16-next.0 + - @backstage/plugin-search-react@1.8.4-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.12-next.2 + +## 1.11.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.3-next.1 + - @backstage/core-components@0.16.2-next.1 + - @backstage/catalog-model@1.7.1 + - @backstage/config@1.3.0 + - @backstage/core-compat-api@0.3.4-next.1 + - @backstage/core-plugin-api@1.10.1 + - @backstage/errors@1.2.5 + - @backstage/frontend-plugin-api@0.9.3-next.1 + - @backstage/integration@1.16.0-next.0 + - @backstage/integration-react@1.2.2-next.0 + - @backstage/theme@0.6.3-next.0 + - @backstage/plugin-auth-react@0.1.10-next.1 + - @backstage/plugin-search-common@1.2.15 + - @backstage/plugin-search-react@1.8.4-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.12-next.1 + +## 1.11.3-next.0 + +### Patch Changes + +- 7d8777d: Added support for the Search bar in docs residing in the entity page tab, and not only the global "/docs" page. +- Updated dependencies + - @backstage/integration@1.16.0-next.0 + - @backstage/plugin-search-react@1.8.4-next.0 + - @backstage/plugin-catalog-react@1.14.3-next.0 + - @backstage/frontend-plugin-api@0.9.3-next.0 + - @backstage/theme@0.6.3-next.0 + - @backstage/catalog-model@1.7.1 + - @backstage/config@1.3.0 + - @backstage/core-compat-api@0.3.4-next.0 + - @backstage/core-components@0.16.2-next.0 + - @backstage/core-plugin-api@1.10.1 + - @backstage/errors@1.2.5 + - @backstage/integration-react@1.2.2-next.0 + - @backstage/plugin-auth-react@0.1.10-next.0 + - @backstage/plugin-search-common@1.2.15 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.12-next.0 + +## 1.11.1 + +### Patch Changes + +- 37a7810: Fixed an issue where `` would re-render infinitely under certain conditions. +- e937ae7: Fix an issue with index page of documentation site being re-rendered. +- 90246a9: Fix techdocs config schema for custom elements sanitizer +- 605bdc0: Avoid page re-rendering when clicking on anchor links in the same documentation page. +- 4f0cb89: Added DomPurify sanitizer configuration for custom elements implementing RFC . + See for how to enable it in the configuration. +- f246178: Removed `canvas` dev dependency. +- 4a2f73a: Fix an issue that caused the current documentation page to be re-rendered when navigating to + another one. +- Updated dependencies + - @backstage/config@1.3.0 + - @backstage/theme@0.6.1 + - @backstage/plugin-catalog-react@1.14.1 + - @backstage/core-components@0.16.0 + - @backstage/plugin-techdocs-react@1.2.10 + - @backstage/catalog-model@1.7.1 + - @backstage/core-compat-api@0.3.2 + - @backstage/core-plugin-api@1.10.1 + - @backstage/errors@1.2.5 + - @backstage/frontend-plugin-api@0.9.1 + - @backstage/integration@1.15.2 + - @backstage/integration-react@1.2.1 + - @backstage/plugin-auth-react@0.1.8 + - @backstage/plugin-search-common@1.2.15 + - @backstage/plugin-search-react@1.8.2 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.11.1-next.3 + +### Patch Changes + +- e937ae7: Fix an issue with index page of documentation site being re-rendered. +- Updated dependencies + - @backstage/core-components@0.16.0-next.2 + - @backstage/plugin-catalog-react@1.14.1-next.3 + - @backstage/core-compat-api@0.3.2-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.10.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.1-next.2 + - @backstage/integration@1.15.1 + - @backstage/integration-react@1.2.0 + - @backstage/theme@0.6.1-next.0 + - @backstage/plugin-auth-react@0.1.8-next.2 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.2-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.10-next.2 + +## 1.11.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.1-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.2-next.1 + - @backstage/core-components@0.16.0-next.1 + - @backstage/core-plugin-api@1.10.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.1-next.1 + - @backstage/integration@1.15.1 + - @backstage/integration-react@1.2.0 + - @backstage/theme@0.6.1-next.0 + - @backstage/plugin-auth-react@0.1.8-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.2-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.10-next.1 + +## 1.11.1-next.1 + +### Patch Changes + +- 90246a9: Fix techdocs config schema for custom elements sanitizer +- Updated dependencies + - @backstage/theme@0.6.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.2-next.1 + - @backstage/core-components@0.16.0-next.1 + - @backstage/core-plugin-api@1.10.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.1-next.1 + - @backstage/integration@1.15.1 + - @backstage/integration-react@1.2.0 + - @backstage/plugin-auth-react@0.1.8-next.1 + - @backstage/plugin-catalog-react@1.14.1-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.2-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.10-next.1 + +## 1.11.1-next.0 + +### Patch Changes + +- 605bdc0: Avoid page re-rendering when clicking on anchor links in the same documentation page. +- 4f0cb89: Added DomPurify sanitizer configuration for custom elements implementing RFC . + See for how to enable it in the configuration. +- f246178: Removed `canvas` dev dependency. +- 4a2f73a: Fix an issue that caused the current documentation page to be re-rendered when navigating to + another one. +- Updated dependencies + - @backstage/core-components@0.16.0-next.0 + - @backstage/plugin-techdocs-react@1.2.10-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.2-next.0 + - @backstage/core-plugin-api@1.10.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.1-next.0 + - @backstage/integration@1.15.1 + - @backstage/integration-react@1.2.0 + - @backstage/theme@0.6.0 + - @backstage/plugin-auth-react@0.1.8-next.0 + - @backstage/plugin-catalog-react@1.14.1-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.2-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.11.0 + +### Minor Changes + +- e77ff3d: Adds support for custom background colors in code blocks and inline code within TechDocs. + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- a77cb40: Make `emptyState` input optional on `entity-content:techdocs` extension so that + the default empty state extension works correctly. +- e918061: Add support for mkdocs material palette conditional hashes. +- 720a2f9: Updated dependency `git-url-parse` to `^15.0.0`. +- e8b4966: Use more of the available space for the navigation sidebar. +- Updated dependencies + - @backstage/core-components@0.15.1 + - @backstage/frontend-plugin-api@0.9.0 + - @backstage/integration-react@1.2.0 + - @backstage/core-compat-api@0.3.1 + - @backstage/core-plugin-api@1.10.0 + - @backstage/plugin-techdocs-react@1.2.9 + - @backstage/plugin-catalog-react@1.14.0 + - @backstage/plugin-search-react@1.8.1 + - @backstage/plugin-auth-react@0.1.7 + - @backstage/theme@0.6.0 + - @backstage/integration@1.15.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.11.0-next.2 + +### Minor Changes + +- e77ff3d: Adds support for custom background colors in code blocks and inline code within TechDocs. + +### Patch Changes + +- e918061: Add support for mkdocs material palette conditional hashes. +- 720a2f9: Updated dependency `git-url-parse` to `^15.0.0`. +- e8b4966: Use more of the available space for the navigation sidebar. +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.0-next.2 + - @backstage/integration@1.15.1-next.1 + - @backstage/theme@0.6.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.1-next.2 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.0-next.2 + - @backstage/integration-react@1.2.0-next.2 + - @backstage/plugin-auth-react@0.1.7-next.2 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.1-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.9-next.2 + +## 1.10.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/plugin-auth-react@0.1.7-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.10-next.0 + +### Patch Changes + +- a77cb40: Make `emptyState` input optional on `entity-content:techdocs` extension so that + the default empty state extension works correctly. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.7-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## 1.10.9 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. + +- fe94ad8: Fixes left navigation positioning when using mkdocs blog plugin + +- b0206dc: Added support for setting page status with 'new' and 'deprecated' values, allowing visual indication of page status in TechDocs. To use include the following at the top of your markdown file: + + ```markdown + --- + status: new + --- + ``` + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- c7cb4c0: Add `empty-state:techdocs/entity-content` extension to allow overriding the empty state for the entity page techdocs tab. + +- 97db53e: Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.6 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.9-next.2 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 97db53e: Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-auth-react@0.1.6-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-compat-api@0.3.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.6-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + +## 1.10.9-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-search-react@1.8.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.8 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- c7603e8: Deprecate the old pattern of `create*Extension`, and replace it with the equivalent Blueprint implementation instead +- 27794d1: Allow for more granular control of TechDocsReaderPage styling. Theme overrides can now be provided to TechDocs without affecting the theme in other areas of Backstage. +- 4490d73: Refactor TechDocs' mkdocs-redirects support. +- 8543e72: TechDocs redirect feature now includes a notification to the user before they are redirected. +- 67e76f2: TechDocs now supports the `mkdocs-redirects` plugin. Redirects defined using the `mkdocs-redirect` plugin will be handled automatically in TechDocs. Redirecting to external urls is not supported. In the case that an external redirect url is provided, TechDocs will redirect to the current documentation site home. +- bdc5471: Fixed issue where header styles were incorrectly generated when themes used CSS variables to define font size. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-plugin-api@0.7.0 + - @backstage/plugin-catalog-react@1.12.3 + - @backstage/plugin-search-react@1.7.14 + - @backstage/core-components@0.14.10 + - @backstage/core-compat-api@0.2.8 + - @backstage/plugin-search-common@1.2.14 + - @backstage/integration@1.14.0 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-auth-react@0.1.5 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-react@1.2.7 + +## 1.10.8-next.3 + +### Patch Changes + +- 27794d1: Allow for more granular control of TechDocsReaderPage styling. Theme overrides can now be provided to TechDocs without affecting the theme in other areas of Backstage. +- 8543e72: TechDocs redirect feature now includes a notification to the user before they are redirected. +- Updated dependencies + - @backstage/frontend-plugin-api@0.7.0-next.3 + - @backstage/catalog-model@1.6.0-next.0 + - @backstage/core-compat-api@0.2.8-next.3 + - @backstage/plugin-catalog-react@1.12.3-next.3 + - @backstage/plugin-search-react@1.7.14-next.3 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-search-common@1.2.14-next.1 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.1 + +## 1.10.8-next.2 + +### Patch Changes + +- 67e76f2: TechDocs now supports the `mkdocs-redirects` plugin. Redirects defined using the `mkdocs-redirect` plugin will be handled automatically in TechDocs. Redirecting to external urls is not supported. In the case that an external redirect url is provided, TechDocs will redirect to the current documentation site home. +- bdc5471: Fixed issue where header styles were incorrectly generated when themes used CSS variables to define font size. +- Updated dependencies + - @backstage/frontend-plugin-api@0.7.0-next.2 + - @backstage/core-compat-api@0.2.8-next.2 + - @backstage/plugin-search-common@1.2.14-next.1 + - @backstage/plugin-search-react@1.7.14-next.2 + - @backstage/plugin-catalog-react@1.12.3-next.2 + - @backstage/integration@1.14.0-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## 1.10.8-next.1 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## 1.10.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## 1.10.7 + +### Patch Changes + +- 8fc2622: Fixed an issue that was causing techdocs pages unnecessarily re-render on navigate. +- 6fa652c: Improve default sorting of docs table +- 605b691: Allow for searching TechDocs by entity title +- 60caa92: Fix double scrollbar bug in reader +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-auth-react@0.1.4 + - @backstage/plugin-search-react@1.7.13 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + +## 1.10.7-next.2 + +### Patch Changes + +- 6fa652c: Improve default sorting of docs table +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-auth-react@0.1.4-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + +## 1.10.7-next.1 + +### Patch Changes + +- 60caa92: Fix double scrollbar bug in reader +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + +## 1.10.7-next.0 + +### Patch Changes + +- 8ac9ce5: Fixed a bug with the TechDocsReaderPageProvider not re-rendering when setShadowDom is called, meaning that the useShadowDom hooks were inconsistent. This issue caused the TextSize addon changes not to reapply during navigation. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/plugin-search-common@1.2.12 + +## 1.10.6 + +### Patch Changes + +- 654af4a: mkdocs-material have updated their CSS variable template, and a few are unset in Backstage. This patch adds the missing variables to ensure coverage. +- cbebad1: Internal updates to allow reusing Backstage's `fetchApi` implementation for event source requests. This allows you to for example, override the `Authorization` header. +- 96cd13e: `TechDocsIndexPage` now accepts an optional `ownerPickerMode` for toggling the behavior of the `EntityOwnerPicker`, exposing a new mode `` particularly suitable for larger catalogs. In this new mode, `EntityOwnerPicker` will display all the users and groups present in the catalog. +- e40bd9a: Fixed bug in `CopyToClipboardButton` component where positioning of the "Copy to clipboard" button in techdocs code snippets was broken in some cases. +- d44a20a: Added additional plugin metadata to `package.json`. +- 1256d88: Fixed an issue preventing the `TechDocsSearchBar` component from opening when clicking on the arrow icon. +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-compat-api@0.2.6 + - @backstage/integration@1.12.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-react@1.2.5 + - @backstage/plugin-catalog-react@1.12.1 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-search-react@1.7.12 + - @backstage/plugin-auth-react@0.1.3 + - @backstage/integration-react@1.1.28 + - @backstage/frontend-plugin-api@0.6.6 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 1.10.6-next.2 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/core-components@0.14.8-next.2 + - @backstage/integration@1.12.0-next.1 + - @backstage/plugin-techdocs-react@1.2.5-next.2 + - @backstage/plugin-catalog-react@1.12.1-next.2 + - @backstage/plugin-search-common@1.2.12-next.0 + - @backstage/plugin-search-react@1.7.12-next.2 + - @backstage/plugin-auth-react@0.1.3-next.2 + - @backstage/integration-react@1.1.28-next.1 + - @backstage/frontend-plugin-api@0.6.6-next.2 + - @backstage/core-compat-api@0.2.6-next.2 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3-next.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6-next.0 + +## 1.10.6-next.1 + +### Patch Changes + +- cbebad1: Internal updates to allow reusing Backstage's `fetchApi` implementation for event source requests. This allows you to for example, override the `Authorization` header. +- Updated dependencies + - @backstage/core-components@0.14.8-next.1 + - @backstage/core-compat-api@0.2.6-next.1 + - @backstage/core-plugin-api@1.9.3-next.0 + - @backstage/integration@1.12.0-next.0 + - @backstage/frontend-plugin-api@0.6.6-next.1 + - @backstage/integration-react@1.1.28-next.0 + - @backstage/plugin-auth-react@0.1.3-next.1 + - @backstage/plugin-catalog-react@1.12.1-next.1 + - @backstage/plugin-search-react@1.7.12-next.1 + - @backstage/plugin-techdocs-react@1.2.5-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.6-next.0 + +### Patch Changes + +- 654af4a: mkdocs-material have updated their CSS variable template, and a few are unset in Backstage. This patch adds the missing variables to ensure coverage. +- 96cd13e: `TechDocsIndexPage` now accepts an optional `ownerPickerMode` for toggling the behavior of the `EntityOwnerPicker`, exposing a new mode `` particularly suitable for larger catalogs. In this new mode, `EntityOwnerPicker` will display all the users and groups present in the catalog. +- e40bd9a: Fixed bug in CopyToClipboardButton component where positioning of the "Copy to clipboard" button in techdocs code snippets was broken in some cases +- 1256d88: Fix weird opening behaviour of the component. +- Updated dependencies + - @backstage/theme@0.5.6-next.0 + - @backstage/core-components@0.14.8-next.0 + - @backstage/plugin-search-react@1.7.12-next.0 + - @backstage/plugin-techdocs-react@1.2.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.6-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.6-next.0 + - @backstage/integration@1.11.0 + - @backstage/integration-react@1.1.27 + - @backstage/plugin-auth-react@0.1.3-next.0 + - @backstage/plugin-catalog-react@1.12.1-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.5 + +### Patch Changes + +- d2cc139: Update path in Readme for Plugin Techdocs to show the correct setup information. +- 5863cf7: The `techdocs.builder` config is now optional and it will default to `local`. +- Updated dependencies + - @backstage/core-compat-api@0.2.5 + - @backstage/core-components@0.14.7 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-react@0.1.2 + - @backstage/plugin-catalog-react@1.12.0 + - @backstage/theme@0.5.4 + - @backstage/integration@1.11.0 + - @backstage/frontend-plugin-api@0.6.5 + - @backstage/integration-react@1.1.27 + - @backstage/plugin-search-react@1.7.11 + - @backstage/plugin-techdocs-react@1.2.4 + +## 1.10.5-next.2 + +### Patch Changes + +- 5863cf7: The `techdocs.builder` config is now optional and it will default to `local`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.0-next.2 + - @backstage/core-components@0.14.7-next.2 + - @backstage/integration@1.11.0-next.0 + - @backstage/core-compat-api@0.2.5-next.1 + - @backstage/frontend-plugin-api@0.6.5-next.1 + - @backstage/plugin-search-react@1.7.11-next.1 + - @backstage/integration-react@1.1.27-next.0 + +## 1.10.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.6-next.1 + - @backstage/plugin-catalog-react@1.11.4-next.1 + - @backstage/frontend-plugin-api@0.6.5-next.1 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-auth-react@0.1.2-next.1 + - @backstage/plugin-search-react@1.7.11-next.1 + - @backstage/plugin-techdocs-react@1.2.4-next.1 + - @backstage/core-compat-api@0.2.5-next.1 + +## 1.10.5-next.0 + +### Patch Changes + +- d2cc139: Update path in Readme for Plugin Techdocs to show the correct setup information. +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-react@0.1.1-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration@1.10.0 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + +## 1.10.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-auth-react@0.1.0 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/integration-react@1.1.26 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-react@0.1.0-next.1 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-auth-react@0.0.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.10.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-auth-react@0.0.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/plugin-techdocs-react@1.2.1 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/plugin-search-react@1.7.8 + - @backstage/frontend-plugin-api@0.6.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-auth-react@0.0.2 + - @backstage/core-compat-api@0.2.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.1 + +### Patch Changes + +- 7c2d022: Fixed bug in TechDocs sidebar render that prevented scrollbar from being displayed +- 3f14e9f: Implement a client cookie refresh mechanism. +- 62bcaf8: Use the new generic refresh user cookie provider. +- 28f27f0: Added ESLint rule `no-top-level-material-ui-4-imports` to aid with the migration to Material UI v5. +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-react@0.0.1 + - @backstage/theme@0.5.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-search-react@1.7.7 + +## 1.10.1-next.2 + +### Patch Changes + +- 7c2d022: Fixed bug in TechDocs sidebar render that prevented scrollbar from being displayed +- 3f14e9f: Implement a client cookie refresh mechanism. +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.10.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + +## 1.10.0 + +### Minor Changes + +- af4d147: Updated the styling for `` tags to avoid word break. + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 3631fb4: Updated dependency `dompurify` to `^3.0.0`. + Updated dependency `@types/dompurify` to `^3.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-search-common@1.2.10 + +## 1.10.0-next.3 + +### Patch Changes + +- 3631fb4: Updated dependency `dompurify` to `^3.0.0`. + Updated dependency `@types/dompurify` to `^3.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/theme@0.5.1-next.1 + - @backstage/integration@1.9.0-next.1 + - @backstage/core-components@0.14.0-next.2 + - @backstage/plugin-catalog-react@1.10.0-next.3 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/config@1.1.1 + - @backstage/core-compat-api@0.2.0-next.3 + - @backstage/core-plugin-api@1.9.0-next.1 + - @backstage/errors@1.2.3 + - @backstage/frontend-plugin-api@0.6.0-next.3 + - @backstage/integration-react@1.1.24-next.2 + - @backstage/plugin-search-common@1.2.10 + - @backstage/plugin-search-react@1.7.6-next.3 + - @backstage/plugin-techdocs-react@1.1.16-next.2 + +## 1.10.0-next.2 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0-next.1 + - @backstage/plugin-techdocs-react@1.1.16-next.1 + - @backstage/core-plugin-api@1.9.0-next.1 + - @backstage/frontend-plugin-api@0.6.0-next.2 + - @backstage/plugin-catalog-react@1.10.0-next.2 + - @backstage/plugin-search-react@1.7.6-next.2 + - @backstage/theme@0.5.1-next.0 + - @backstage/integration-react@1.1.24-next.1 + - @backstage/core-compat-api@0.2.0-next.2 + - @backstage/config@1.1.1 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/errors@1.2.3 + - @backstage/integration@1.9.0-next.0 + - @backstage/plugin-search-common@1.2.10 + +## 1.10.0-next.1 + +### Minor Changes + +- af4d147: Updated the styling for `` tags to avoid word break. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0-next.1 + - @backstage/core-compat-api@0.2.0-next.1 + - @backstage/core-components@0.14.0-next.0 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/core-plugin-api@1.8.3-next.0 + - @backstage/integration@1.9.0-next.0 + - @backstage/plugin-catalog-react@1.9.4-next.1 + - @backstage/plugin-search-react@1.7.6-next.1 + - @backstage/integration-react@1.1.24-next.0 + - @backstage/plugin-techdocs-react@1.1.16-next.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.10 + +## 1.9.4-next.0 + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- Updated dependencies + - @backstage/core-compat-api@0.1.2-next.0 + - @backstage/plugin-catalog-react@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.5.1-next.0 + - @backstage/core-components@0.13.10 + - @backstage/plugin-search-react@1.7.6-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/integration-react@1.1.23 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.10 + - @backstage/plugin-techdocs-react@1.1.15 + +## 1.9.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.10 + +## 1.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.1.1-next.2 + - @backstage/frontend-plugin-api@0.4.1-next.2 + - @backstage/plugin-catalog-react@1.9.3-next.2 + - @backstage/plugin-search-react@1.7.5-next.2 + - @backstage/integration-react@1.1.23-next.0 + +## 1.9.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2-next.0 + - @backstage/core-components@0.13.10-next.1 + - @backstage/core-compat-api@0.1.1-next.1 + - @backstage/frontend-plugin-api@0.4.1-next.1 + - @backstage/integration-react@1.1.23-next.0 + - @backstage/plugin-catalog-react@1.9.3-next.1 + - @backstage/plugin-search-react@1.7.5-next.1 + - @backstage/plugin-techdocs-react@1.1.15-next.1 + - @backstage/integration@1.8.0 + - @backstage/config@1.1.1 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.9 + +## 1.9.3-next.0 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10-next.0 + - @backstage/frontend-plugin-api@0.4.1-next.0 + - @backstage/plugin-techdocs-react@1.1.15-next.0 + - @backstage/plugin-catalog-react@1.9.3-next.0 + - @backstage/integration-react@1.1.22 + - @backstage/plugin-search-react@1.7.5-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-compat-api@0.1.1-next.0 + - @backstage/core-plugin-api@1.8.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.9 + +## 1.9.2 + +### Patch Changes + +- 03d0b6d: The `convertLegacyRouteRef` utility used by the alpha exports is now imported from `@backstage/core-compat-api`. +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 5814122: Updated `/alpha` exports to fit new naming patterns. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/core-compat-api@0.1.0 + - @backstage/core-plugin-api@1.8.1 + - @backstage/frontend-plugin-api@0.4.0 + - @backstage/plugin-catalog-react@1.9.2 + - @backstage/core-components@0.13.9 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-react@1.7.4 + - @backstage/integration@1.8.0 + - @backstage/integration-react@1.1.22 + - @backstage/plugin-techdocs-react@1.1.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.9 + +## 1.9.2-next.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.9-next.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-compat-api@0.1.0-next.3 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/frontend-plugin-api@0.4.0-next.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.3 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-search-react@1.7.4-next.3 + - @backstage/plugin-techdocs-react@1.1.14-next.3 + +## 1.9.2-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + +## 1.9.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.1 + - @backstage/core-components@0.13.9-next.1 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.1 + - @backstage/plugin-search-react@1.7.4-next.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/core-compat-api@0.0.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-techdocs-react@1.1.14-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0-next.0 + - @backstage/plugin-search-common@1.2.8 + +## 1.9.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.0.1-next.0 + +## 1.9.2-next.0 + +### Patch Changes + +- 03d0b6dcdc: The `convertLegacyRouteRef` utility used by the alpha exports is now imported from `@backstage/core-compat-api`. +- Updated dependencies + - @backstage/core-compat-api@0.0.2-next.0 + - @backstage/core-plugin-api@1.8.1-next.0 + - @backstage/plugin-catalog-react@1.9.2-next.0 + - @backstage/core-components@0.13.9-next.0 + - @backstage/plugin-search-react@1.7.4-next.0 + - @backstage/integration@1.8.0-next.0 + - @backstage/theme@0.5.0-next.0 + - @backstage/frontend-plugin-api@0.3.1-next.0 + - @backstage/integration-react@1.1.22-next.0 + - @backstage/plugin-techdocs-react@1.1.14-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.8 + +## 1.9.0 + +### Minor Changes + +- 17f93d5589: A new analytics event `not-found` will be published when a user visits a documentation site that does not exist + +### Patch Changes + +- 4728b3960d: Fixed navigation bug that caused users to not be scrolled to the top of a new page. Fixed navigation bug where using backwards and forwards browser navigation did not scroll users to the correct place on the TechDoc page. +- a3add7a682: Export alpha routes and nav item extension, only available for applications that uses the new Frontend system. +- 71c97e7d73: The \`spec.lifecycle' field in entities will now always be rendered as a string. +- 68fc9dc60e: Updated alpha exports according to routing changes in `@backstage/frontend-plugin-api`. +- 6c2b872153: Add official support for React 18. +- 0bf6ebda88: Added entity page content for the new plugin exported via `/alpha`. +- 67cc85bb14: Switched the conditional `react-dom/client` import to use `import(...)` rather than `require(...)`. +- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. +- 38cda52746: Added support for React 18. The new `createRoot` API from `react-dom/client` will now be used if present. +- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency +- Updated dependencies + - @backstage/plugin-catalog-react@1.9.0 + - @backstage/core-components@0.13.8 + - @backstage/frontend-plugin-api@0.3.0 + - @backstage/integration@1.7.2 + - @backstage/integration-react@1.1.21 + - @backstage/core-plugin-api@1.8.0 + - @backstage/plugin-techdocs-react@1.1.13 + - @backstage/plugin-search-react@1.7.2 + - @backstage/theme@0.4.4 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.8 + +## 1.9.0-next.2 + +### Minor Changes + +- [#20851](https://github.com/backstage/backstage/pull/20851) [`17f93d5589`](https://github.com/backstage/backstage/commit/17f93d5589812df3dea53d956212e184b080fbac) Thanks [@agentbellnorm](https://github.com/agentbellnorm)! - A new analytics event `not-found` will be published when a user visits a documentation site that does not exist + +### Patch Changes + +- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency + +- Updated dependencies + - @backstage/core-components@0.13.8-next.2 + - @backstage/frontend-plugin-api@0.3.0-next.2 + - @backstage/plugin-catalog-react@1.9.0-next.2 + - @backstage/integration-react@1.1.21-next.1 + - @backstage/plugin-search-react@1.7.2-next.2 + - @backstage/plugin-techdocs-react@1.1.13-next.2 + +## 1.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.2-next.0 + - @backstage/frontend-plugin-api@0.3.0-next.1 + - @backstage/plugin-catalog-react@1.9.0-next.1 + - @backstage/plugin-search-react@1.7.2-next.1 + - @backstage/integration-react@1.1.21-next.1 + - @backstage/core-components@0.13.8-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-plugin-api@1.8.0-next.0 + - @backstage/errors@1.2.3 + - @backstage/theme@0.4.4-next.0 + - @backstage/plugin-search-common@1.2.7 + - @backstage/plugin-techdocs-react@1.1.13-next.1 + +## 1.8.1-next.0 + +### Patch Changes + +- 4728b3960d: Fixed navigation bug that caused users to not be scrolled to the top of a new page. Fixed navigation bug where using backwards and forwards browser navigation did not scroll users to the correct place on the TechDoc page. +- a3add7a682: Export alpha routes and nav item extension, only available for applications that uses the new Frontend system. +- 71c97e7d73: The \`spec.lifecycle' field in entities will now always be rendered as a string. +- 68fc9dc60e: Updated alpha exports according to routing changes in `@backstage/frontend-plugin-api`. +- 6c2b872153: Add official support for React 18. +- 0bf6ebda88: Added entity page content for the new plugin exported via `/alpha`. +- 67cc85bb14: Switched the conditional `react-dom/client` import to use `import(...)` rather than `require(...)`. +- 38cda52746: Added support for React 18. The new `createRoot` API from `react-dom/client` will now be used if present. +- Updated dependencies + - @backstage/core-components@0.13.7-next.0 + - @backstage/frontend-plugin-api@0.3.0-next.0 + - @backstage/plugin-catalog-react@1.9.0-next.0 + - @backstage/integration-react@1.1.21-next.0 + - @backstage/core-plugin-api@1.8.0-next.0 + - @backstage/plugin-techdocs-react@1.1.13-next.0 + - @backstage/plugin-search-react@1.7.2-next.0 + - @backstage/theme@0.4.4-next.0 + - @backstage/integration@1.7.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.7 + +## 1.8.0 + +### Minor Changes + +- 27740caa2d: Added experimental support for declarative integration via the `/alpha` subpath. + +### Patch Changes + +- 4918f65ab2: Create an experimental `TechDocsSearchResultItemExtension` for declarative integration with Backstage; it can be accessed via the `/alpha` import. +- 3605370af6: Improved `DocsTable` to display pagination controls dynamically, appearing only when needed. +- 0296f272b4: The \`spec.lifecycle' field in entities will now always be rendered as a string. +- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. +- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. +- 9468a67b92: Added support for React 18. The new `createRoot` API from `react-dom/client` will now be used if present. +- df449a7a31: Add kind column by default to TechDocsTable +- Updated dependencies + - @backstage/integration@1.7.1 + - @backstage/plugin-catalog-react@1.8.5 + - @backstage/frontend-plugin-api@0.2.0 + - @backstage/core-plugin-api@1.7.0 + - @backstage/core-components@0.13.6 + - @backstage/integration-react@1.1.20 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-react@1.7.1 + - @backstage/plugin-techdocs-react@1.1.12 + - @backstage/theme@0.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.7 + +## 1.7.1-next.2 + +### Patch Changes + +- 3605370af6: Improved `DocsTable` to display pagination controls dynamically, appearing only when needed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.2.0-next.2 + - @backstage/integration-react@1.1.20-next.2 + - @backstage/core-components@0.13.6-next.2 + - @backstage/core-plugin-api@1.7.0-next.1 + - @backstage/catalog-model@1.4.3-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.2 + - @backstage/integration@1.7.1-next.1 + - @backstage/errors@1.2.3-next.0 + - @backstage/plugin-search-react@1.7.1-next.2 + - @backstage/theme@0.4.3-next.0 + - @backstage/config@1.1.1-next.0 + - @backstage/plugin-search-common@1.2.7-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.2 + +## 1.7.1-next.1 + +### Patch Changes + +- 4918f65ab2: Create an experimental `TechDocsSearchResultItemExtension` for declarative integration with Backstage; it can be accessed via the `/alpha` import. +- df449a7a31: Add kind column by default to TechDocsTable +- Updated dependencies + - @backstage/frontend-plugin-api@0.1.1-next.1 + - @backstage/core-components@0.13.6-next.1 + - @backstage/plugin-search-react@1.7.1-next.1 + - @backstage/integration-react@1.1.20-next.1 + - @backstage/plugin-catalog-react@1.8.5-next.1 + - @backstage/plugin-techdocs-react@1.1.12-next.1 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/integration@1.7.1-next.0 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + +## 1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + +## 1.7.0 + +### Minor Changes + +- e44f45ac4515: This change allows a new annotation of `backstage.io/techdocs-entity` this ref allows you to reference another entity for its TechDocs. This allows you have a single TechDoc for all items in a system, for example you might have a frontend and a backend in the same repo. This would allow you to have TechDocs build under a `System` entity while referencing the system e.g.: `backstage.io/techdocs-entity: system:default/example` that will show the systems docs in both the TechDocs button and the TechDocs tab without needing to do duplicate builds and filling the TechDocs page with garbage. + +### Patch Changes + +- 88c9525a36f3: Fixed bug in styles that caused next and previous links in footer to overlap page content. +- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/integration-react@1.1.19 + - @backstage/plugin-catalog-react@1.8.4 + - @backstage/core-components@0.13.5 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/core-plugin-api@1.6.0 + - @backstage/errors@1.2.2 + - @backstage/integration@1.7.0 + - @backstage/plugin-search-common@1.2.6 + - @backstage/plugin-search-react@1.7.0 + - @backstage/plugin-techdocs-react@1.1.10 + - @backstage/theme@0.4.2 + +## 1.7.0-next.3 + +### Patch Changes + +- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. +- Updated dependencies + - @backstage/catalog-model@1.4.2-next.2 + - @backstage/config@1.1.0-next.2 + - @backstage/core-components@0.13.5-next.3 + - @backstage/core-plugin-api@1.6.0-next.3 + - @backstage/errors@1.2.2-next.0 + - @backstage/integration@1.7.0-next.3 + - @backstage/integration-react@1.1.19-next.3 + - @backstage/plugin-catalog-react@1.8.4-next.3 + - @backstage/plugin-search-common@1.2.6-next.2 + - @backstage/plugin-search-react@1.7.0-next.3 + - @backstage/plugin-techdocs-react@1.1.10-next.3 + - @backstage/theme@0.4.2-next.0 + +## 1.7.0-next.2 + +### Minor Changes + +- e44f45ac4515: This change allows a new annotation of `backstage.io/techdocs-entity` this ref allows you to reference another entity for its TechDocs. This allows you have a single TechDoc for all items in a system, for example you might have a frontend and a backend in the same repo. This would allow you to have TechDocs build under a `System` entity while referencing the system e.g.: `backstage.io/techdocs-entity: system:default/example` that will show the systems docs in both the TechDocs button and the TechDocs tab without needing to do duplicate builds and filling the TechDocs page with garbage. + +### Patch Changes + +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/integration-react@1.1.19-next.2 + - @backstage/core-components@0.13.5-next.2 + - @backstage/core-plugin-api@1.6.0-next.2 + - @backstage/config@1.1.0-next.1 + - @backstage/plugin-catalog-react@1.8.4-next.2 + - @backstage/plugin-search-react@1.7.0-next.2 + - @backstage/plugin-techdocs-react@1.1.10-next.2 + - @backstage/integration@1.7.0-next.2 + - @backstage/catalog-model@1.4.2-next.1 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-search-common@1.2.6-next.1 + +## 1.6.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.4-next.1 + - @backstage/core-components@0.13.5-next.1 + - @backstage/config@1.1.0-next.0 + - @backstage/integration@1.7.0-next.1 + - @backstage/plugin-search-react@1.7.0-next.1 + - @backstage/integration-react@1.1.19-next.1 + - @backstage/plugin-techdocs-react@1.1.10-next.1 + - @backstage/catalog-model@1.4.2-next.0 + - @backstage/core-plugin-api@1.6.0-next.1 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-search-common@1.2.6-next.0 + +## 1.6.8-next.0 + +### Patch Changes + +- 88c9525a36f3: Fixed bug in styles that caused next and previous links in footer to overlap page content. +- Updated dependencies + - @backstage/integration-react@1.1.18-next.0 + - @backstage/integration@1.7.0-next.0 + - @backstage/core-plugin-api@1.6.0-next.0 + - @backstage/core-components@0.13.5-next.0 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-catalog-react@1.8.3-next.0 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-search-react@1.6.5-next.0 + - @backstage/plugin-techdocs-react@1.1.10-next.0 + +## 1.6.6 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.1.16 + - @backstage/integration@1.6.0 + - @backstage/core-components@0.13.4 + - @backstage/plugin-catalog-react@1.8.1 + - @backstage/core-plugin-api@1.5.3 + - @backstage/plugin-search-react@1.6.4 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-techdocs-react@1.1.9 + +## 1.6.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.1-next.1 + - @backstage/integration-react@1.1.16-next.1 + +## 1.6.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.1.16-next.1 + - @backstage/integration@1.5.1 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/core-components@0.13.4-next.0 + - @backstage/core-plugin-api@1.5.3 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-catalog-react@1.8.1-next.0 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-search-react@1.6.4-next.0 + - @backstage/plugin-techdocs-react@1.1.9-next.0 + +## 1.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.4-next.0 + - @backstage/core-plugin-api@1.5.3 + - @backstage/plugin-catalog-react@1.8.1-next.0 + - @backstage/plugin-search-react@1.6.4-next.0 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/integration@1.5.1 + - @backstage/integration-react@1.1.16-next.0 + - @backstage/theme@0.4.1 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-techdocs-react@1.1.9-next.0 + +## 1.6.5 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.4.1 + - @backstage/errors@1.2.1 + - @backstage/plugin-catalog-react@1.8.0 + - @backstage/core-components@0.13.3 + - @backstage/core-plugin-api@1.5.3 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/integration@1.5.1 + - @backstage/integration-react@1.1.15 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-search-react@1.6.3 + - @backstage/plugin-techdocs-react@1.1.8 + +## 1.6.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.0-next.2 + - @backstage/theme@0.4.1-next.1 + - @backstage/core-plugin-api@1.5.3-next.1 + - @backstage/core-components@0.13.3-next.2 + - @backstage/catalog-model@1.4.1-next.0 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1-next.0 + - @backstage/integration@1.5.1-next.0 + - @backstage/integration-react@1.1.15-next.2 + - @backstage/plugin-search-common@1.2.5-next.0 + - @backstage/plugin-search-react@1.6.3-next.2 + - @backstage/plugin-techdocs-react@1.1.8-next.2 + +## 1.6.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.4.1-next.0 + - @backstage/core-components@0.13.3-next.1 + - @backstage/core-plugin-api@1.5.3-next.0 + - @backstage/integration-react@1.1.15-next.1 + - @backstage/plugin-catalog-react@1.7.1-next.1 + - @backstage/plugin-search-react@1.6.3-next.1 + - @backstage/plugin-techdocs-react@1.1.8-next.1 + - @backstage/config@1.0.8 + +## 1.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.1-next.0 + - @backstage/core-components@0.13.3-next.0 + - @backstage/catalog-model@1.4.1-next.0 + - @backstage/config@1.0.8 + - @backstage/core-plugin-api@1.5.2 + - @backstage/integration@1.5.1-next.0 + - @backstage/integration-react@1.1.15-next.0 + - @backstage/theme@0.4.0 + - @backstage/plugin-catalog-react@1.7.1-next.0 + - @backstage/plugin-search-common@1.2.5-next.0 + - @backstage/plugin-search-react@1.6.3-next.0 + - @backstage/plugin-techdocs-react@1.1.8-next.0 + +## 1.6.4 + +### Patch Changes + +- 2f660eb573cc: Fix SearchBar styles & update StoryBook stories for custom styles for `notchedOutline` class. +- 956d09e8ea68: Change deprecated local references to import from shared `plugin-techdocs-react` plugin +- e33beb1f2a8e: Make the documentation pages printable (also handy for exporting to PDF) +- Updated dependencies + - @backstage/core-plugin-api@1.5.2 + - @backstage/plugin-search-react@1.6.2 + - @backstage/core-components@0.13.2 + - @backstage/theme@0.4.0 + - @backstage/integration@1.5.0 + - @backstage/plugin-catalog-react@1.7.0 + - @backstage/catalog-model@1.4.0 + - @backstage/errors@1.2.0 + - @backstage/plugin-techdocs-react@1.1.7 + - @backstage/integration-react@1.1.14 + - @backstage/config@1.0.8 + - @backstage/plugin-search-common@1.2.4 + +## 1.6.4-next.3 + +### Patch Changes + +- e33beb1f2a8e: Make the documentation pages printable (also handy for exporting to PDF) +- Updated dependencies + - @backstage/plugin-search-react@1.6.2-next.3 + - @backstage/core-components@0.13.2-next.3 + - @backstage/catalog-model@1.4.0-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.2-next.0 + - @backstage/errors@1.2.0-next.0 + - @backstage/integration@1.5.0-next.0 + - @backstage/integration-react@1.1.14-next.3 + - @backstage/theme@0.4.0-next.1 + - @backstage/plugin-catalog-react@1.7.0-next.3 + - @backstage/plugin-search-common@1.2.4-next.0 + - @backstage/plugin-techdocs-react@1.1.7-next.3 + +## 1.6.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.4.0-next.1 + - @backstage/plugin-catalog-react@1.7.0-next.2 + - @backstage/core-components@0.13.2-next.2 + - @backstage/integration-react@1.1.14-next.2 + - @backstage/plugin-search-react@1.6.1-next.2 + - @backstage/plugin-techdocs-react@1.1.7-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.2-next.0 + +## 1.6.3-next.1 + +### Patch Changes + +- 2f660eb573cc: Fix SearchBar styles & update StoryBook stories for custom styles for `notchedOutline` class. +- Updated dependencies + - @backstage/integration@1.5.0-next.0 + - @backstage/errors@1.2.0-next.0 + - @backstage/plugin-search-react@1.6.1-next.1 + - @backstage/core-components@0.13.2-next.1 + - @backstage/plugin-catalog-react@1.7.0-next.1 + - @backstage/catalog-model@1.4.0-next.0 + - @backstage/core-plugin-api@1.5.2-next.0 + - @backstage/integration-react@1.1.14-next.1 + - @backstage/plugin-techdocs-react@1.1.7-next.1 + - @backstage/config@1.0.7 + - @backstage/theme@0.4.0-next.0 + - @backstage/plugin-search-common@1.2.4-next.0 + +## 1.6.3-next.0 + +### Patch Changes + +- 956d09e8ea68: Change deprecated local references to import from shared `plugin-techdocs-react` plugin +- Updated dependencies + - @backstage/plugin-catalog-react@1.7.0-next.0 + - @backstage/theme@0.4.0-next.0 + - @backstage/plugin-techdocs-react@1.1.7-next.0 + - @backstage/integration@1.4.5 + - @backstage/config@1.0.7 + - @backstage/core-components@0.13.2-next.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/integration-react@1.1.14-next.0 + - @backstage/plugin-search-react@1.6.1-next.0 + - @backstage/catalog-model@1.3.0 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.6.2 + +### Patch Changes + +- 863beb49498: Re-add the possibility to have trailing slashes in Techdocs navigation. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.6.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## 1.6.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-catalog-react@1.6.0-next.1 + - @backstage/plugin-search-react@1.6.0-next.1 + - @backstage/integration-react@1.1.13-next.1 + - @backstage/plugin-techdocs-react@1.1.6-next.0 + - @backstage/config@1.0.7 + +## 1.6.2-next.0 + +### Patch Changes + +- 863beb49498: Re-add the possibility to have trailing slashes in Techdocs navigation. +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0-next.0 + - @backstage/integration@1.4.5-next.0 + - @backstage/plugin-search-react@1.6.0-next.0 + - @backstage/integration-react@1.1.13-next.0 + - @backstage/core-components@0.13.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/theme@0.2.19 + - @backstage/plugin-search-common@1.2.3 + - @backstage/plugin-techdocs-react@1.1.5 + +## 1.6.1 + +### Patch Changes + +- 6c809d1a41c: Minor visual tweaks to adapt to changes in mkdocs-material v9 + +- b2e182cdfa4: Fixes a UI bug in search result item which rendered the item text with incorrect font size and color + +- 847a1eee3da: Change anchor links color in Techdocs content + + With the color (mkdocs supplied) used for anchor links the background and foreground colors do not have a sufficient contrast ratio. Using the link color from theme palette. + +- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) + +- 2e493480626: Fix a bug in sub-path navigation due to double addition of a sub-path if one was set up in `app.baseUrl`. + +- e0c6e8b9c3c: Update peer dependencies + +- Updated dependencies + - @backstage/core-components@0.13.0 + - @backstage/plugin-catalog-react@1.5.0 + - @backstage/plugin-search-react@1.5.2 + - @backstage/plugin-techdocs-react@1.1.5 + - @backstage/integration-react@1.1.12 + - @backstage/theme@0.2.19 + - @backstage/core-plugin-api@1.5.1 + - @backstage/catalog-model@1.3.0 + - @backstage/integration@1.4.4 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.6.1-next.3 + +### Patch Changes + +- 2e493480626: Fix a bug in sub-path navigation due to double addition of a sub-path if one was set up in `app.baseUrl`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.5.0-next.3 + - @backstage/catalog-model@1.3.0-next.0 + - @backstage/core-components@0.13.0-next.3 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1-next.1 + - @backstage/errors@1.1.5 + - @backstage/integration@1.4.4-next.0 + - @backstage/integration-react@1.1.12-next.3 + - @backstage/theme@0.2.19-next.0 + - @backstage/plugin-search-common@1.2.3-next.0 + - @backstage/plugin-search-react@1.5.2-next.3 + - @backstage/plugin-techdocs-react@1.1.5-next.3 + +## 1.6.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.6-next.2 + - @backstage/plugin-catalog-react@1.4.1-next.2 + - @backstage/core-plugin-api@1.5.1-next.1 + - @backstage/catalog-model@1.2.1 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/integration@1.4.4-next.0 + - @backstage/integration-react@1.1.12-next.2 + - @backstage/theme@0.2.19-next.0 + - @backstage/plugin-search-common@1.2.3-next.0 + - @backstage/plugin-search-react@1.5.2-next.2 + - @backstage/plugin-techdocs-react@1.1.5-next.2 + +## 1.6.1-next.1 + +### Patch Changes + +- 6c809d1a41c: Minor visual tweaks to adapt to changes in mkdocs-material v9 + +- 847a1eee3da: Change anchor links color in Techdocs content + + With the color (mkdocs supplied) used for anchor links the background and foreground colors do not have a sufficient contrast ratio. Using the link color from theme palette. + +- e0c6e8b9c3c: Update peer dependencies + +- Updated dependencies + - @backstage/core-components@0.12.6-next.1 + - @backstage/integration-react@1.1.12-next.1 + - @backstage/core-plugin-api@1.5.1-next.0 + - @backstage/plugin-techdocs-react@1.1.5-next.1 + - @backstage/plugin-catalog-react@1.4.1-next.1 + - @backstage/integration@1.4.4-next.0 + - @backstage/plugin-search-react@1.5.2-next.1 + - @backstage/theme@0.2.19-next.0 + - @backstage/catalog-model@1.2.1 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3-next.0 + +## 1.6.1-next.0 + +### Patch Changes + +- b2e182cdfa4: Fixes a UI bug in search result item which rendered the item text with incorrect font size and color +- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) +- Updated dependencies + - @backstage/core-components@0.12.6-next.0 + - @backstage/plugin-search-react@1.5.2-next.0 + - @backstage/plugin-techdocs-react@1.1.5-next.0 + - @backstage/plugin-catalog-react@1.4.1-next.0 + - @backstage/integration-react@1.1.12-next.0 + - @backstage/core-plugin-api@1.5.0 + - @backstage/config@1.0.7 + - @backstage/integration@1.4.3 + - @backstage/catalog-model@1.2.1 + - @backstage/errors@1.1.5 + - @backstage/theme@0.2.18 + - @backstage/plugin-search-common@1.2.2 + +## 1.6.0 + +### Minor Changes + +- 3f75b7607ca: Add ability to pass icon as function to have ability to customize it by search item + +### Patch Changes + +- 65454876fb2: Minor API report tweaks +- 54a1e133b56: Fix bug that caused next and previous links not to work with certain versions of mkdocs-material +- f320c299c67: The HTML tag attributes in the documentation content inserted to shadow DOM is preserved to improve accessibility +- cb8ec97cdeb: Change black & white colors to be theme aware +- c10384a9235: Switch to using `LinkButton` instead of the deprecated `Button` +- 8adfda60ae1: Updated dependency `jss` to `~10.10.0`. +- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. +- 238cf657c09: Copy to clipboard now works in a not secure context. +- Updated dependencies + - @backstage/core-components@0.12.5 + - @backstage/plugin-techdocs-react@1.1.4 + - @backstage/plugin-catalog-react@1.4.0 + - @backstage/plugin-search-react@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/core-plugin-api@1.5.0 + - @backstage/catalog-model@1.2.1 + - @backstage/integration-react@1.1.11 + - @backstage/integration@1.4.3 + - @backstage/config@1.0.7 + - @backstage/theme@0.2.18 + - @backstage/plugin-search-common@1.2.2 + +## 1.6.0-next.2 + +### Patch Changes + +- 65454876fb2: Minor API report tweaks +- Updated dependencies + - @backstage/core-components@0.12.5-next.2 + - @backstage/plugin-techdocs-react@1.1.4-next.2 + - @backstage/plugin-catalog-react@1.4.0-next.2 + - @backstage/plugin-search-react@1.5.1-next.2 + - @backstage/core-plugin-api@1.5.0-next.2 + - @backstage/integration-react@1.1.11-next.2 + - @backstage/config@1.0.7-next.0 + - @backstage/integration@1.4.3-next.0 + +## 1.6.0-next.1 + +### Patch Changes + +- 54a1e133b56: Fix bug that caused next and previous links not to work with certain versions of mkdocs-material +- cb8ec97cdeb: Change black & white colors to be theme aware +- c10384a9235: Switch to using `LinkButton` instead of the deprecated `Button` +- 8adfda60ae1: Updated dependency `jss` to `~10.10.0`. +- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. +- 238cf657c09: Copy to clipboard now works in a not secure context. +- Updated dependencies + - @backstage/core-components@0.12.5-next.1 + - @backstage/errors@1.1.5-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.1 + - @backstage/core-plugin-api@1.4.1-next.1 + - @backstage/integration-react@1.1.11-next.1 + - @backstage/integration@1.4.3-next.0 + - @backstage/config@1.0.7-next.0 + - @backstage/theme@0.2.18-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.1 + - @backstage/catalog-model@1.2.1-next.1 + - @backstage/plugin-search-common@1.2.2-next.0 + - @backstage/plugin-search-react@1.5.1-next.1 + +## 1.6.0-next.0 + +### Minor Changes + +- 3f75b7607c: Add ability to pass icon as function to have ability to customize it by search item + +### Patch Changes + +- f320c299c6: The HTML tag attributes in the documentation content inserted to shadow DOM is preserved to improve accessibility +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 1.5.0 + +### Minor Changes + +- 20840b36b4: Update DocsTable and EntityListDocsTable to accept overrides for Material Table options. +- 0eaa579f89: The `TechDocsSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- c8e09cc383: Fixed bug in Techdocs reader where a techdocs page with a hash in the URL did not always jump to the document anchor. + +- cad5607411: Improve view: remove footer overlay on large screen + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- 4660b63947: Create a TechDocs `` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. + + Here's an example on how to use it in a Backstage app: + + ```diff + import { + DefaultTechDocsHome, + TechDocsIndexPage, + TechDocsReaderPage, + } from '@backstage/plugin-techdocs'; + import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; + +import { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib'; + + const AppRoutes = () => { + + // other plugin routes + }> + + + } + > + + + + + + ; + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-react@1.1.3 + +## 1.5.0-next.2 + +### Patch Changes + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- Updated dependencies + - @backstage/catalog-model@1.2.0-next.1 + - @backstage/plugin-search-react@1.5.0-next.1 + - @backstage/core-components@0.12.4-next.1 + - @backstage/config@1.0.6 + - @backstage/core-plugin-api@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.3.0-next.2 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-react@1.1.3-next.2 + +## 1.5.0-next.1 + +### Minor Changes + +- 20840b36b4: Update DocsTable and EntityListDocsTable to accept overrides for Material Table options. +- 0eaa579f89: The `TechDocsSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4-next.0 + - @backstage/plugin-search-react@1.5.0-next.0 + - @backstage/plugin-catalog-react@1.3.0-next.1 + - @backstage/catalog-model@1.1.6-next.0 + - @backstage/config@1.0.6 + - @backstage/core-plugin-api@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-react@1.1.3-next.1 + +## 1.4.4-next.0 + +### Patch Changes + +- c8e09cc383: Fixed bug in Techdocs reader where a techdocs page with a hash in the URL did not always jump to the document anchor. +- cad5607411: Improve view: remove footer overlay on large screen +- Updated dependencies + - @backstage/plugin-catalog-react@1.3.0-next.0 + - @backstage/catalog-model@1.1.6-next.0 + - @backstage/plugin-techdocs-react@1.1.3-next.0 + - @backstage/integration-react@1.1.9 + +## 1.4.3 + +### Patch Changes + +- a74dd61534: Fix sizing of build log component to render all lines +- 80ce4e8c29: Small updates to some components to ensure theme typography properties are inherited correctly. +- 7115c7389b: Updated dependency `jss` to `~10.9.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.5 + - @backstage/plugin-catalog-react@1.2.4 + - @backstage/core-components@0.12.3 + - @backstage/plugin-search-react@1.4.0 + - @backstage/core-plugin-api@1.3.0 + - @backstage/plugin-techdocs-react@1.1.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.9 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.1 + +## 1.4.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.4.0-next.2 + - @backstage/core-plugin-api@1.3.0-next.1 + - @backstage/plugin-catalog-react@1.2.4-next.2 + - @backstage/plugin-techdocs-react@1.1.2-next.2 + - @backstage/catalog-model@1.1.5-next.1 + - @backstage/config@1.0.6-next.0 + - @backstage/core-components@0.12.3-next.2 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2-next.0 + - @backstage/integration-react@1.1.9-next.2 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.1-next.0 + +## 1.4.3-next.1 + +### Patch Changes + +- a74dd61534: Fix sizing of build log component to render all lines +- Updated dependencies + - @backstage/config@1.0.6-next.0 + - @backstage/catalog-model@1.1.5-next.1 + - @backstage/core-components@0.12.3-next.1 + - @backstage/core-plugin-api@1.2.1-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2-next.0 + - @backstage/integration-react@1.1.9-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.4-next.1 + - @backstage/plugin-search-common@1.2.1-next.0 + - @backstage/plugin-search-react@1.3.2-next.1 + - @backstage/plugin-techdocs-react@1.1.2-next.1 + +## 1.4.3-next.0 + +### Patch Changes + +- 7115c7389b: Updated dependency `jss` to `~10.9.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.5-next.0 + - @backstage/plugin-catalog-react@1.2.4-next.0 + - @backstage/core-components@0.12.3-next.0 + - @backstage/plugin-techdocs-react@1.1.2-next.0 + - @backstage/config@1.0.5 + - @backstage/core-plugin-api@1.2.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.1 + - @backstage/integration-react@1.1.9-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.0 + - @backstage/plugin-search-react@1.3.2-next.0 + +## 1.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.2 + - @backstage/integration-react@1.1.8 + - @backstage/plugin-catalog-react@1.2.3 + - @backstage/plugin-search-react@1.3.1 + - @backstage/plugin-techdocs-react@1.1.1 + +## 1.4.1 + +### Patch Changes + +- d3fea4ae0a: Internal fixes to avoid implicit usage of globals +- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. +- a19cffbeed: Update search links to only have header as linkable text +- 5d3058355d: Add `react/forbid-elements` linter rule for button, suggest Material UI `Button` +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 786f1b1419: Support older versions of react-router +- Updated dependencies + - @backstage/plugin-techdocs-react@1.1.0 + - @backstage/core-plugin-api@1.2.0 + - @backstage/plugin-search-react@1.3.0 + - @backstage/core-components@0.12.1 + - @backstage/errors@1.1.4 + - @backstage/plugin-catalog-react@1.2.2 + - @backstage/integration-react@1.1.7 + - @backstage/integration@1.4.1 + - @backstage/plugin-search-common@1.2.0 + - @backstage/catalog-model@1.1.4 + - @backstage/config@1.0.5 + - @backstage/theme@0.2.16 + +## 1.4.1-next.4 + +### Patch Changes + +- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.4 + - @backstage/plugin-catalog-react@1.2.2-next.4 + - @backstage/plugin-search-react@1.3.0-next.4 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/errors@1.1.4-next.1 + - @backstage/integration@1.4.1-next.1 + - @backstage/integration-react@1.1.7-next.4 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.0-next.3 + - @backstage/plugin-techdocs-react@1.0.7-next.4 + +## 1.4.1-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.3 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/errors@1.1.4-next.1 + - @backstage/integration@1.4.1-next.1 + - @backstage/integration-react@1.1.7-next.3 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.2-next.3 + - @backstage/plugin-search-common@1.2.0-next.2 + - @backstage/plugin-search-react@1.3.0-next.3 + - @backstage/plugin-techdocs-react@1.0.7-next.3 + +## 1.4.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/plugin-search-react@1.3.0-next.2 + - @backstage/core-components@0.12.1-next.2 + - @backstage/plugin-catalog-react@1.2.2-next.2 + - @backstage/plugin-search-common@1.2.0-next.2 + - @backstage/integration-react@1.1.7-next.2 + - @backstage/plugin-techdocs-react@1.0.7-next.2 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/errors@1.1.4-next.1 + - @backstage/integration@1.4.1-next.1 + - @backstage/theme@0.2.16 + +## 1.4.1-next.1 + +### Patch Changes + +- d3fea4ae0a: Internal fixes to avoid implicit usage of globals +- a19cffbeed: Update search links to only have header as linkable text +- Updated dependencies + - @backstage/core-components@0.12.1-next.1 + - @backstage/plugin-search-react@1.2.2-next.1 + - @backstage/core-plugin-api@1.1.1-next.1 + - @backstage/plugin-catalog-react@1.2.2-next.1 + - @backstage/integration-react@1.1.7-next.1 + - @backstage/plugin-techdocs-react@1.0.7-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/integration@1.4.1-next.1 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/errors@1.1.4-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.2-next.1 + +## 1.4.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + +## 1.4.0 + +### Minor Changes + +- 5691baea69: Add ability to configure filters when using EntityListDocsGrid + + The following example will render two sections of cards grid: + + - One section for documentations tagged as `recommended` + - One section for documentations tagged as `runbook` + + ```js + + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + { + title: "RunBooks Documentation", + filterPredicate: entity => + entity?.metadata?.tags?.includes('runbook') ?? false, + } + ]}} /> + ``` + +- 63705e73d9: Hide document description if not provided + +- 847fc588a6: Updated TechDocs header to include label for source code icon and updated label to reflect Kind name + +### Patch Changes + +- 9e4d8e6198: Fix logic bug that broke techdocs-cli-embedded-app +- e92aa15f01: Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. +- cbe11d1e23: Tweak README +- 7573b65232: Internal refactor of imports to avoid circular dependencies +- c1784a4980: Replaces in-code uses of `GitHub` with `Github` and deprecates old versions. +- 3a1a999b7b: Include query parameters when navigating to relative links in documents +- bd2aab4726: An analytics event matching the semantics of the `click` action is now captured when users click links within a TechDocs document. +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.1 + - @backstage/core-components@0.12.0 + - @backstage/core-plugin-api@1.1.0 + - @backstage/integration@1.4.0 + - @backstage/catalog-model@1.1.3 + - @backstage/plugin-techdocs-react@1.0.6 + - @backstage/integration-react@1.1.6 + - @backstage/plugin-search-react@1.2.1 + - @backstage/config@1.0.4 + - @backstage/errors@1.1.3 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.1 + +## 1.4.0-next.2 + +### Patch Changes + +- e92aa15f01: Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + +## 1.4.0-next.1 + +### Patch Changes + +- 9e4d8e6198: Fix logic bug that broke techdocs-cli-embedded-app + +## 1.4.0-next.0 + +### Minor Changes + +- 5691baea69: Add ability to configure filters when using EntityListDocsGrid + + The following example will render two sections of cards grid: + + - One section for documentations tagged as `recommended` + - One section for documentations tagged as `runbook` + + ```js + + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + { + title: "RunBooks Documentation", + filterPredicate: entity => + entity?.metadata?.tags?.includes('runbook') ?? false, + } + ]}} /> + ``` + +### Patch Changes + +- cbe11d1e23: Tweak README +- 7573b65232: Internal refactor of imports to avoid circular dependencies +- c1784a4980: Replaces in-code uses of `GitHub` with `Github` and deprecates old versions. +- 3a1a999b7b: Include query parameters when navigating to relative links in documents +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.1-next.0 + - @backstage/core-components@0.12.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/integration-react@1.1.6-next.0 + - @backstage/plugin-search-react@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.0.6-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.1-next.0 + +## 1.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.2 + - @backstage/plugin-catalog-react@1.2.0 + - @backstage/core-components@0.11.2 + - @backstage/plugin-search-react@1.2.0 + - @backstage/plugin-search-common@1.1.0 + - @backstage/plugin-techdocs-react@1.0.5 + - @backstage/integration-react@1.1.5 + - @backstage/core-plugin-api@1.0.7 + - @backstage/config@1.0.3 + - @backstage/errors@1.1.2 + - @backstage/integration@1.3.2 + - @backstage/theme@0.2.16 + +## 1.3.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.0-next.2 + - @backstage/plugin-search-common@1.1.0-next.2 + - @backstage/catalog-model@1.1.2-next.2 + - @backstage/config@1.0.3-next.2 + - @backstage/core-components@0.11.2-next.2 + - @backstage/core-plugin-api@1.0.7-next.2 + - @backstage/errors@1.1.2-next.2 + - @backstage/integration@1.3.2-next.2 + - @backstage/integration-react@1.1.5-next.2 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-react@1.2.0-next.2 + - @backstage/plugin-techdocs-react@1.0.5-next.2 + +## 1.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.0-next.1 + - @backstage/plugin-search-react@1.2.0-next.1 + - @backstage/plugin-search-common@1.1.0-next.1 + - @backstage/core-components@0.11.2-next.1 + - @backstage/core-plugin-api@1.0.7-next.1 + - @backstage/catalog-model@1.1.2-next.1 + - @backstage/config@1.0.3-next.1 + - @backstage/errors@1.1.2-next.1 + - @backstage/integration@1.3.2-next.1 + - @backstage/integration-react@1.1.5-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-techdocs-react@1.0.5-next.1 + +## 1.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.2-next.0 + - @backstage/core-components@0.11.2-next.0 + - @backstage/plugin-catalog-react@1.1.5-next.0 + - @backstage/plugin-techdocs-react@1.0.5-next.0 + - @backstage/integration-react@1.1.5-next.0 + - @backstage/plugin-search-react@1.1.1-next.0 + - @backstage/config@1.0.3-next.0 + - @backstage/core-plugin-api@1.0.7-next.0 + - @backstage/errors@1.1.2-next.0 + - @backstage/integration@1.3.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.0.2-next.0 + +## 1.3.2 + +### Patch Changes + +- 817f3196f6: Updated React Router dependencies to be peer dependencies. +- eadf56bbbf: Bump `git-url-parse` version to `^13.0.0` +- 3f739be9d9: Minor API signatures cleanup +- 763fb81e82: Internal refactor to use more type safe code when dealing with route parameters. +- 7d47def9c4: Removed dependency on `@types/jest`. +- 817f3196f6: Updated the `TechDocsReaderPage` to be compatible with React Router v6 stable. +- 7a95c705fa: Fixed a bug where addons wouldn't render on sub pages when using React Route v6 stable. +- 667d917488: Updated dependency `msw` to `^0.47.0`. +- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. +- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. +- ca8d5a6eae: Use the new `SearchAutocomplete` component in the `TechDocsSearch` component to maintain consistency across search experiences and avoid code duplication. +- 829f14a9b0: Always update the title and sub-title when the location changes on a `TechDocs` reader page. +- e97d616f08: Fixed a bug where scrolling for anchors where the id starts with number didn't work for the current page. +- ef9ab322de: Minor API signatures cleanup +- Updated dependencies + - @backstage/core-components@0.11.1 + - @backstage/core-plugin-api@1.0.6 + - @backstage/plugin-catalog-react@1.1.4 + - @backstage/plugin-search-react@1.1.0 + - @backstage/plugin-techdocs-react@1.0.4 + - @backstage/integration@1.3.1 + - @backstage/catalog-model@1.1.1 + - @backstage/config@1.0.2 + - @backstage/errors@1.1.1 + - @backstage/integration-react@1.1.4 + - @backstage/plugin-search-common@1.0.1 + +## 1.3.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + +## 1.3.2-next.2 + +### Patch Changes + +- eadf56bbbf: Bump `git-url-parse` version to `^13.0.0` +- 7a95c705fa: Fixed a bug where addons wouldn't render on sub pages when using React Route v6 stable. +- 667d917488: Updated dependency `msw` to `^0.47.0`. +- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. +- ca8d5a6eae: Use the new `SearchAutocomplete` component in the `TechDocsSearch` component to maintain consistency across search experiences and avoid code duplication. +- e97d616f08: Fixed a bug where scrolling for anchors where the id starts with number didn't work for the current page. +- Updated dependencies + - @backstage/integration@1.3.1-next.1 + - @backstage/core-components@0.11.1-next.2 + - @backstage/core-plugin-api@1.0.6-next.2 + - @backstage/integration-react@1.1.4-next.1 + - @backstage/plugin-search-react@1.1.0-next.2 + +## 1.3.2-next.1 + +### Patch Changes + +- 817f3196f6: Updated React Router dependencies to be peer dependencies. +- 763fb81e82: Internal refactor to use more type safe code when dealing with route parameters. +- 817f3196f6: Updated the `TechDocsReaderPage` to be compatible with React Router v6 stable. +- Updated dependencies + - @backstage/core-components@0.11.1-next.1 + - @backstage/core-plugin-api@1.0.6-next.1 + - @backstage/plugin-catalog-react@1.1.4-next.1 + - @backstage/plugin-search-react@1.0.2-next.1 + - @backstage/plugin-techdocs-react@1.0.4-next.1 + +## 1.3.2-next.0 + +### Patch Changes + +- 3f739be9d9: Minor API signatures cleanup +- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. +- 829f14a9b0: Always update the title and sub-title when the location changes on a `TechDocs` reader page. +- ef9ab322de: Minor API signatures cleanup +- Updated dependencies + - @backstage/core-plugin-api@1.0.6-next.0 + - @backstage/core-components@0.11.1-next.0 + - @backstage/integration-react@1.1.4-next.0 + - @backstage/integration@1.3.1-next.0 + - @backstage/plugin-catalog-react@1.1.4-next.0 + - @backstage/plugin-search-react@1.0.2-next.0 + - @backstage/plugin-techdocs-react@1.0.4-next.0 + - @backstage/plugin-search-common@1.0.1-next.0 + +## 1.3.1 + +### Patch Changes + +- e924d2d013: Added back reduction in size, this fixes the extremely large TeachDocs headings +- b86ed4d990: Add highlight to active navigation item and navigation parents. +- 7a98c73dc8: Fixed techdocs sidebar layout bug for medium devices. +- 8acb22205c: Scroll techdocs navigation into focus and expand any nested navigation items. +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## 1.3.1-next.2 + +### Patch Changes + +- 8acb22205c: Scroll techdocs navigation into focus and expand any nested navigation items. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## 1.3.1-next.1 + +### Patch Changes + +- b86ed4d990: Add highlight to active navigation item and navigation parents. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## 1.3.1-next.0 + +### Patch Changes + +- 7a98c73dc8: Fixed techdocs sidebar layout bug for medium devices. +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## 1.3.0 + +### Minor Changes + +- ebf3eb1641: Use the same initial filter `owned` for the `TechDocsIndexPage` as for the `CatalogPage`. + + If you prefer to keep the previous behavior, you can change the default for the initial filter + to `all` (or `starred` if you rather prefer that). + + + + In general, with this change you will be able to set props at `TechDocsIndexPage`. + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 3cbebf710e: Reorder browser tab title in Techdocs pages to have the site name first. + +- 726577958f: Remove the 60% factor from the font size calculation of headers to use the exact size defined in BackstageTheme. + +- 7739141ab2: Fix: When docs are shown in an entity page under the docs tab the sidebars start overlapping with the header and tabs in the page when you scroll the documentation content. + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## 1.2.1-next.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.4-next.0 + - @backstage/core-components@0.10.0-next.3 + - @backstage/integration-react@1.1.2-next.3 + - @backstage/integration@1.2.2-next.3 + - @backstage/catalog-model@1.1.0-next.3 + - @backstage/plugin-catalog-react@1.1.2-next.3 + - @backstage/plugin-search-react@0.2.2-next.3 + - @backstage/plugin-techdocs-react@1.0.2-next.2 + +## 1.2.1-next.2 + +### Patch Changes + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 7739141ab2: Fix: When docs are shown in an entity page under the docs tab the sidebars start overlapping with the header and tabs in the page when you scroll the documentation content. + +- Updated dependencies + - @backstage/core-components@0.10.0-next.2 + - @backstage/catalog-model@1.1.0-next.2 + - @backstage/plugin-search-react@0.2.2-next.2 + - @backstage/theme@0.2.16-next.1 + - @backstage/integration@1.2.2-next.2 + - @backstage/plugin-catalog-react@1.1.2-next.2 + - @backstage/integration-react@1.1.2-next.2 + - @backstage/plugin-techdocs-react@1.0.2-next.1 + +## 1.2.1-next.1 + +### Patch Changes + +- 726577958f: Remove the 60% factor from the font size calculation of headers to use the exact size defined in BackstageTheme. +- Updated dependencies + - @backstage/core-components@0.9.6-next.1 + - @backstage/catalog-model@1.1.0-next.1 + - @backstage/errors@1.1.0-next.0 + - @backstage/theme@0.2.16-next.0 + - @backstage/integration@1.2.2-next.1 + - @backstage/integration-react@1.1.2-next.1 + - @backstage/plugin-catalog-react@1.1.2-next.1 + - @backstage/plugin-search-common@0.3.6-next.0 + - @backstage/plugin-search-react@0.2.2-next.1 + +## 1.2.1-next.0 + +### Patch Changes + +- 3cbebf710e: Reorder browser tab title in Techdocs pages to have the site name first. +- Updated dependencies + - @backstage/catalog-model@1.1.0-next.0 + - @backstage/core-components@0.9.6-next.0 + - @backstage/plugin-techdocs-react@1.0.2-next.0 + - @backstage/integration@1.2.2-next.0 + - @backstage/plugin-catalog-react@1.1.2-next.0 + - @backstage/integration-react@1.1.2-next.0 + - @backstage/plugin-search-react@0.2.2-next.0 + +## 1.2.0 + +### Minor Changes + +- fe7614ea54: Add an optional icon to the Catalog and TechDocs search results + +### Patch Changes + +- d047d81295: Use entity title as label in `TechDocsReaderPageHeader` if available + +- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. + +- bff65e6958: Updated sidebar-related logic to use `` + `useSidebarPinState()` and/or `` + `useSidebarOpenState()` from `@backstage/core-components`. + +- 915700f64f: In order to simplify analytics on top of the search experience in Backstage, the provided `<*ResultListItem />` component now captures a `discover` analytics event instead of a `click` event. This event includes the result rank as its `value` and, like a click, the URL/path clicked to as its `to` attribute. + +- 881fbd7e8d: Fix `EntityTechdocsContent` component to use objects instead of `` elements, otherwise "outlet" will be null on sub-pages and add-ons won't render. + +- 17c059dfd0: Restructures reader style transformations to improve code readability: + + - Extracts the style rules to separate files; + - Creates a hook that processes each rule; + - And creates another hook that returns a transformer responsible for injecting them into the head tag of a given element. + +- 3b45ad701f: Packages a set of tweaks to the TechDocs addons rendering process: + + - Prevents displaying sidebars until page styles are loaded and the sidebar position is updated; + - Prevents new sidebar locations from being created every time the reader page is rendered if these locations already exist; + - Centers the styles loaded event to avoid having multiple locations setting the opacity style in Shadow Dom causing the screen to flash multiple times. + +- 9b94ade898: Use entity title in `TechDocsSearch` placeholder if available. + +- 816f7475ec: Convert `sanitizeDOM` transformer to hook as part of code readability improvements in dom file. + +- 50ff56a80f: Change the `EntityDocsPage` path to be more specific and also add integration tests for `sub-routes` on this page. + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.1 + - @backstage/plugin-search-common@0.3.5 + - @backstage/plugin-search-react@0.2.1 + - @backstage/core-components@0.9.5 + - @backstage/integration@1.2.1 + - @backstage/core-plugin-api@1.0.3 + - @backstage/integration-react@1.1.1 + - @backstage/catalog-model@1.0.3 + - @backstage/plugin-techdocs-react@1.0.1 + +## 1.1.2-next.1 + +### Patch Changes + +- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. +- bff65e6958: Updated sidebar-related logic to use `` + `useSidebarPinState()` and/or `` + `useSidebarOpenState()` from `@backstage/core-components`. +- Updated dependencies + - @backstage/core-components@0.9.5-next.1 + - @backstage/core-plugin-api@1.0.3-next.0 + - @backstage/integration-react@1.1.1-next.1 + - @backstage/integration@1.2.1-next.1 + - @backstage/catalog-model@1.0.3-next.0 + - @backstage/plugin-catalog-react@1.1.1-next.1 + - @backstage/plugin-search-react@0.2.1-next.0 + - @backstage/plugin-techdocs-react@1.0.1-next.1 + - @backstage/plugin-search-common@0.3.5-next.0 + +## 1.1.2-next.0 + +### Patch Changes + +- 881fbd7e8d: Fix `EntityTechdocsContent` component to use objects instead of `` elements, otherwise "outlet" will be null on sub-pages and add-ons won't render. + +- 17c059dfd0: Restructures reader style transformations to improve code readability: + + - Extracts the style rules to separate files; + - Creates a hook that processes each rule; + - And creates another hook that returns a transformer responsible for injecting them into the head tag of a given element. + +- 3b45ad701f: Packages a set of tweaks to the TechDocs addons rendering process: + + - Prevents displaying sidebars until page styles are loaded and the sidebar position is updated; + - Prevents new sidebar locations from being created every time the reader page is rendered if these locations already exist; + - Centers the styles loaded event to avoid having multiple locations setting the opacity style in Shadow Dom causing the screen to flash multiple times. + +- 816f7475ec: Convert `sanitizeDOM` transformer to hook as part of code readability improvements in dom file. + +- 50ff56a80f: Change the `EntityDocsPage` path to be more specific and also add integration tests for `sub-routes` on this page. + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.1-next.0 + - @backstage/core-components@0.9.5-next.0 + - @backstage/integration@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.0.1-next.0 + - @backstage/integration-react@1.1.1-next.0 + +## 1.1.1 + +### Patch Changes + +- 52419be116: Create a menu in the sub header of documentation pages, it is responsible for rendering TechDocs addons that allow users to customize their reading experience. +- a307a14be0: Removed dependency on `@backstage/core-app-api`. +- bed0d64ce9: Fixed bugs that prevented a 404 error from being shown when it should have been. +- 2efee91251: Add a `sub-route` path on the EntityDocs page to fix the blank screen error when navigating using sidebar links. +- 2dcb2c9678: Loading SVGs correctly with `bota` with extended characters +- 52fddad92d: The `TechDocsStorageApi` and its associated ref are now exported by `@backstage/plugin-techdocs-react`. The API interface, ref, and types are now deprecated in `@backstage/plugin-techdocs` and will be removed in a future release. +- 0ad901569f: Hidden exports related to experimental TechDocs reader functionality have been removed and can no longer be imported. In the unlikely event you were using these exports, you can now take advantage of the officially supported and generally available TechDocs Addon framework instead. +- 3a74e203a8: Updated search result components to support rendering content with highlighted matched terms +- Updated dependencies + - @backstage/core-components@0.9.4 + - @backstage/integration@1.2.0 + - @backstage/core-plugin-api@1.0.2 + - @backstage/plugin-catalog-react@1.1.0 + - @backstage/integration-react@1.1.0 + - @backstage/plugin-techdocs-react@1.0.0 + - @backstage/config@1.0.1 + - @backstage/plugin-search-react@0.2.0 + - @backstage/plugin-search-common@0.3.4 + - @backstage/catalog-model@1.0.2 + +## 1.1.1-next.3 + +### Patch Changes + +- cc8ddd0979: revert dependency `event-source-polyfill` to `1.0.25` +- Updated dependencies + - @backstage/core-components@0.9.4-next.2 + +## 1.1.1-next.2 + +### Patch Changes + +- 52419be116: Create a menu in the sub header of documentation pages, it is responsible for rendering TechDocs addons that allow users to customize their reading experience. +- 1af133f779: Updated dependency `event-source-polyfill` to `1.0.26`. +- 2dcb2c9678: Loading SVGs correctly with `bota` with extended characters +- 3a74e203a8: Updated search result components to support rendering content with highlighted matched terms +- Updated dependencies + - @backstage/core-components@0.9.4-next.1 + - @backstage/plugin-techdocs-react@0.1.1-next.2 + - @backstage/config@1.0.1-next.0 + - @backstage/plugin-search-react@0.2.0-next.2 + - @backstage/plugin-search-common@0.3.4-next.0 + - @backstage/plugin-catalog-react@1.1.0-next.2 + - @backstage/catalog-model@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.2-next.1 + - @backstage/integration@1.2.0-next.1 + - @backstage/integration-react@1.1.0-next.2 + +## 1.1.1-next.1 + +### Patch Changes + +- 52fddad92d: The `TechDocsStorageApi` and its associated ref are now exported by `@backstage/plugin-techdocs-react`. The API interface, ref, and types are now deprecated in `@backstage/plugin-techdocs` and will be removed in a future release. +- Updated dependencies + - @backstage/core-components@0.9.4-next.0 + - @backstage/core-plugin-api@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.1.0-next.1 + - @backstage/plugin-search-react@0.2.0-next.1 + - @backstage/plugin-techdocs-react@0.1.1-next.1 + - @backstage/integration-react@1.1.0-next.1 + +## 1.1.1-next.0 + +### Patch Changes + +- a307a14be0: Removed dependency on `@backstage/core-app-api`. +- bed0d64ce9: Fixed bugs that prevented a 404 error from being shown when it should have been. +- Updated dependencies + - @backstage/integration@1.2.0-next.0 + - @backstage/plugin-catalog-react@1.1.0-next.0 + - @backstage/integration-react@1.1.0-next.0 + - @backstage/plugin-search-react@0.1.1-next.0 + - @backstage/plugin-techdocs-react@0.1.1-next.0 + +## 1.1.0 + +### Minor Changes + +- ace749b785: TechDocs supports a new, experimental method of customization: addons! + + To customize the standalone TechDocs reader page experience, update your `/packages/app/src/App.tsx` in the following way: + + ```diff + import { TechDocsIndexPage, TechDocsReaderPage } from '@backstage/plugin-techdocs'; + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + + import { SomeAddon } from '@backstage/plugin-some-plugin'; + + // ... + + } /> + } + > + + + + + + + + + // ... + ``` + + To customize the TechDocs reader experience on the Catalog entity page, update your `packages/app/src/components/catalog/EntityPage.tsx` in the following way: + + ```diff + import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + + import { SomeAddon } from '@backstage/plugin-some-plugin'; + + // ... + + + + {overviewContent} + + + + - + + + + + + + + + + + + + + // ... + ``` + + If you do not wish to customize your TechDocs reader experience in this way at this time, no changes are necessary! + +### Patch Changes + +- ab230a433f: imports from `@backstage/plugin-search-react` instead of `@backstage/plugin-search` + +- 7c7919777e: build(deps-dev): bump `@testing-library/react-hooks` from 7.0.2 to 8.0.0 + +- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 + +- 230ad0826f: Bump to using `@types/node` v16 + +- f0fb9153b7: Fix broken query selectors on techdocs + +- 9975ff9852: Applied the fix from version 1.0.1 of this package, which is part of the v1.0.2 release of Backstage. + +- 3ba256c389: Fixed a bug preventing custom TechDocs reader page implementations from rendering without being double-wrapped in the `` component. + +- fe53fe97d7: Fix permalink scrolling for anchors where the id starts with a number. + +- 0152c0de22: Some documentation layout tweaks: + + - drawer toggle margins + - code block margins + - sidebar drawer width + - inner content width + - footer link width + - sidebar table of contents scroll + +- 3ba256c389: Fixed a bug that caused addons in the `Subheader` location to break the default TechDocs reader page layout. + +- Updated dependencies + - @backstage/integration@1.1.0 + - @backstage/plugin-catalog-react@1.0.1 + - @backstage/catalog-model@1.0.1 + - @backstage/core-app-api@1.0.1 + - @backstage/core-components@0.9.3 + - @backstage/core-plugin-api@1.0.1 + - @backstage/plugin-search-react@0.1.0 + - @backstage/plugin-techdocs-react@0.1.0 + - @backstage/integration-react@1.0.1 + +## 1.1.0-next.3 + +### Minor Changes + +- ace749b785: TechDocs supports a new, experimental method of customization: addons! + + To customize the standalone TechDocs reader page experience, update your `/packages/app/src/App.tsx` in the following way: + + ```diff + import { TechDocsIndexPage, TechDocsReaderPage } from '@backstage/plugin-techdocs'; + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + + import { SomeAddon } from '@backstage/plugin-some-plugin'; + + // ... + + } /> + } + > + + + + + + + + + // ... + ``` + + To customize the TechDocs reader experience on the Catalog entity page, update your `packages/app/src/components/catalog/EntityPage.tsx` in the following way: + + ```diff + import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + + import { SomeAddon } from '@backstage/plugin-some-plugin'; + + // ... + + + + {overviewContent} + + + + - + + + + + + + + + + + + + + // ... + ``` + + If you do not wish to customize your TechDocs reader experience in this way at this time, no changes are necessary! + +### Patch Changes + +- ab230a433f: imports from `@backstage/plugin-search-react` instead of `@backstage/plugin-search` +- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 +- 230ad0826f: Bump to using `@types/node` v16 +- Updated dependencies + - @backstage/core-app-api@1.0.1-next.1 + - @backstage/core-components@0.9.3-next.2 + - @backstage/core-plugin-api@1.0.1-next.0 + - @backstage/integration-react@1.0.1-next.2 + - @backstage/plugin-catalog-react@1.0.1-next.3 + - @backstage/plugin-search-react@0.1.0-next.0 + - @backstage/integration@1.1.0-next.2 + - @backstage/plugin-techdocs-react@0.1.0-next.0 + +## 1.0.1-next.2 + +### Patch Changes + +- f0fb9153b7: Fix broken query selectors on techdocs +- 9975ff9852: Applied the fix from version 1.0.1 of this package, which is part of the v1.0.2 release of Backstage. +- Updated dependencies + - @backstage/core-components@0.9.3-next.1 + - @backstage/plugin-catalog-react@1.0.1-next.2 + - @backstage/catalog-model@1.0.1-next.1 + +## 1.0.1 + +### Patch Changes + +- Pin the `event-source-polyfill` dependency to version 1.0.25 + +## 1.0.1-next.1 + +### Patch Changes + +- 0152c0de22: Some documentation layout tweaks: + + - drawer toggle margins + - code block margins + - sidebar drawer width + - inner content width + - footer link width + - sidebar table of contents scroll + +- Updated dependencies + - @backstage/integration@1.1.0-next.1 + - @backstage/plugin-catalog-react@1.0.1-next.1 + - @backstage/integration-react@1.0.1-next.1 + +## 1.0.1-next.0 + +### Patch Changes + +- fe53fe97d7: Fix permalink scrolling for anchors where the id starts with a number. +- Updated dependencies + - @backstage/catalog-model@1.0.1-next.0 + - @backstage/plugin-search@0.7.5-next.0 + - @backstage/integration@1.0.1-next.0 + - @backstage/plugin-catalog-react@1.0.1-next.0 + - @backstage/core-components@0.9.3-next.0 + - @backstage/integration-react@1.0.1-next.0 + +## 1.0.0 + +### Major Changes + +- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). + +### Minor Changes + +- 700d93ff41: Removed deprecated exports, including: + + - deprecated `DocsResultListItem` is now deleted and fully replaced with `TechDocsSearchResultListItem` + - deprecated `TechDocsPage` is now deleted and fully replaced with `TechDocsReaderPage` + - deprecated `TechDocsPageHeader` is now deleted and fully replaced with `TechDocsReaderPageHeader` + - deprecated `TechDocsPageHeaderProps` is now deleted and fully replaced with `TechDocsReaderPageHeaderProps` + - deprecated `TechDocsPageRenderFunction` is now deleted and fully replaced with `TechDocsReaderPageRenderFunction` + - deprecated config `techdocs.requestUrl` is now deleted and fully replaced with the discoveryApi + +### Patch Changes + +- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 +- c689d7a94c: Switched to using `CatalogFilterLayout` from `@backstage/plugin-catalog-react`. +- f24ef7864e: Minor typo fixes +- 06af9e8d17: Long sidebars will no longer overflow the footer and will properly show a scrollbar when needed. +- Updated dependencies + - @backstage/core-components@0.9.2 + - @backstage/core-plugin-api@1.0.0 + - @backstage/integration-react@1.0.0 + - @backstage/plugin-catalog-react@1.0.0 + - @backstage/plugin-search@0.7.4 + - @backstage/catalog-model@1.0.0 + - @backstage/integration@1.0.0 + - @backstage/config@1.0.0 + - @backstage/errors@1.0.0 + +## 0.15.1 + +### Patch Changes + +- 7a1dbe6ce9: The panels of `TechDocsCustomHome` now use the `useEntityOwnership` hook to resolve ownership when the `'ownedByUser'` filter predicate is used. +- Updated dependencies + - @backstage/plugin-catalog@0.10.0 + - @backstage/plugin-catalog-react@0.9.0 + - @backstage/core-components@0.9.1 + - @backstage/catalog-model@0.13.0 + - @backstage/plugin-search@0.7.3 + - @backstage/integration-react@0.1.25 + +## 0.15.1-next.0 + +### Patch Changes + +- 7a1dbe6ce9: The panels of `TechDocsCustomHome` now use the `useEntityOwnership` hook to resolve ownership when the `'ownedByUser'` filter predicate is used. +- Updated dependencies + - @backstage/plugin-catalog@0.10.0-next.0 + - @backstage/plugin-catalog-react@0.9.0-next.0 + - @backstage/core-components@0.9.1-next.0 + - @backstage/catalog-model@0.13.0-next.0 + - @backstage/plugin-search@0.7.3-next.0 + - @backstage/integration-react@0.1.25-next.0 + +## 0.15.0 + +### Minor Changes + +- ee3d6c6f10: **BREAKING:** + Table column utilities `createNameColumn`, `createOwnerColumn`, `createTypeColumn` as well as actions utilities `createCopyDocsUrlAction` and `createStarEntityAction` are no longer directly exported. Instead accessible through DocsTable and EntityListDocsTable. + + Use as following: + + ```tsx + DocsTable.columns.createNameColumn(); + DocsTable.columns.createOwnerColumn(); + DocsTable.columns.createTypeColumn(); + + DocsTable.actions.createCopyDocsUrlAction(); + DocsTable.actions.createStarEntityAction(); + ``` + + - Renamed `DocsResultListItem` to `TechDocsSearchResultListItem`, leaving the old name in place as a deprecations. + + - Renamed `TechDocsPage` to `TechDocsReaderPage`, leaving the old name in place as a deprecations. + + - Renamed `TechDocsPageRenderFunction` to `TechDocsPageRenderFunction`, leaving the old name in place as a deprecations. + + - Renamed `TechDocsPageHeader` to `TechDocsReaderPageHeader`, leaving the old name in place as a deprecations. + + - `LegacyTechDocsHome` marked as deprecated and will be deleted in next release, use `TechDocsCustomHome` instead. + + - `LegacyTechDocsPage` marked as deprecated and will be deleted in next release, use `TechDocsReaderPage` instead. + +### Patch Changes + +- 64b430f80d: chore(deps): bump `react-text-truncate` from 0.17.0 to 0.18.0 +- 899f196af5: Use `getEntityByRef` instead of `getEntityByName` in the catalog client +- f41a293231: - **DEPRECATION**: Deprecated `formatEntityRefTitle` in favor of the new `humanizeEntityRef` method instead. Please migrate to using the new method instead. +- c5fda066b1: Collapse techdocs sidebar on small devices +- f590d1681b: Removed usage of deprecated favorite utility methods. +- 5b0f9a75fa: Remove copyright from old footer in documentation generated with previous version of `mkdocs-techdocs-plugin` (`v0.2.2`). +- 0c3ba547a6: Show feedback when copying code snippet to clipboard. +- 0ca964ee0e: Fixed a bug that could cause searches in the in-context TechDocs search bar to show results from a different TechDocs site. +- 36aa63022b: Use `CompoundEntityRef` instead of `EntityName`, and `getCompoundEntityRef` instead of `getEntityName`, from `@backstage/catalog-model`. +- Updated dependencies + - @backstage/catalog-model@0.12.0 + - @backstage/core-components@0.9.0 + - @backstage/plugin-search@0.7.2 + - @backstage/plugin-catalog@0.9.1 + - @backstage/plugin-catalog-react@0.8.0 + - @backstage/integration@0.8.0 + - @backstage/core-plugin-api@0.8.0 + - @backstage/integration-react@0.1.24 + +## 0.14.0 + +### Minor Changes + +- 2262fe19c9: **BREAKING**: Removed support for passing in an explicit `entity` prop to entity page extensions, which has been deprecated for a long time. This is only a breaking change at the TypeScript level, as this property was already ignored. +- 4faae902eb: Adjust the Tech Docs page theme as a side effect of the `mkdocs-material` theme update. + + If you use the `spofify/techdocs` image to build your documentation, make sure you use version `spotify/techdocs:v0.3.7`. + + **Breaking**: The `PyMdown` extensions have also been updated and some syntax may have changed, so it is recommended that you check the extension's documentation if something stops working. + For example, the syntax of tags below was deprecated in `PyMdown` extensions `v.7.0` and in `v.8.0.0` it has been removed. This means that the old syntax specified below no longer works. + + ````markdown + ```markdown tab="tab" + This is some markdown + ``` + + ```markdown tab="tab 2" + This is some markdown in tab 2 + ``` + ```` + +### Patch Changes + +- 3bbb4d98c6: Changed to use from createApp +- ed09ad8093: Updated usage of the `LocationSpec` type from `@backstage/catalog-model`, which is deprecated. +- b776ce5aab: Replaced use of deprecated `useEntityListProvider` hook with `useEntityList`. +- d4f67fa728: Removed import of deprecated hook. +- 45e1706328: Continuation of [#9569](https://github.com/backstage/backstage/pull/9569), fix Tech Docs Reader search position to be the same width as content. +- 919cf2f836: Minor updates to match the new `targetRef` field of relations, and to stop consuming the `target` field +- Updated dependencies + - @backstage/plugin-catalog@0.9.0 + - @backstage/core-components@0.8.10 + - @backstage/plugin-catalog-react@0.7.0 + - @backstage/catalog-model@0.11.0 + - @backstage/core-plugin-api@0.7.0 + - @backstage/integration@0.7.5 + - @backstage/plugin-search@0.7.1 + - @backstage/integration-react@0.1.23 + +## 0.13.4 + +### Patch Changes + +- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 +- c77c5c7eb6: Added `backstage.role` to `package.json` +- 6553985cd4: Match text size of admonitions to main content text size. +- 9df7b43e1a: Improve overall appearance of highlighted code in docs. +- Updated dependencies + - @backstage/core-components@0.8.9 + - @backstage/core-plugin-api@0.6.1 + - @backstage/errors@0.2.1 + - @backstage/integration@0.7.3 + - @backstage/integration-react@0.1.22 + - @backstage/plugin-catalog@0.8.0 + - @backstage/plugin-catalog-react@0.6.15 + - @backstage/plugin-search@0.7.0 + - @backstage/catalog-model@0.10.0 + - @backstage/config@0.1.14 + - @backstage/theme@0.2.15 + +## 0.13.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-search@0.6.2 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/plugin-catalog@0.7.12 + - @backstage/integration-react@0.1.21 + +## 0.13.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8-next.0 + - @backstage/plugin-search@0.6.2-next.0 + - @backstage/plugin-catalog-react@0.6.14-next.0 + - @backstage/integration-react@0.1.21-next.0 + - @backstage/plugin-catalog@0.7.12-next.0 + +## 0.13.2 + +### Patch Changes + +- 742434a6ba: Fixed a bug where links to files within a TechDocs site that use the `download` attribute would result in a 404 in cases where the TechDocs backend and Backstage frontend application are on the same host. +- 359c31e31d: Added support for documentation using the raw `` tag to point to relative resources like audio or video files. +- 18317a08db: Fixed a bug where copy-to-clipboard buttons were appended to unintended elements. +- Updated dependencies + - @backstage/core-components@0.8.7 + - @backstage/plugin-catalog-react@0.6.13 + - @backstage/integration-react@0.1.20 + - @backstage/plugin-catalog@0.7.11 + - @backstage/plugin-search@0.6.1 + +## 0.13.2-next.1 + +### Patch Changes + +- 742434a6ba: Fixed a bug where links to files within a TechDocs site that use the `download` attribute would result in a 404 in cases where the TechDocs backend and Backstage frontend application are on the same host. +- Updated dependencies + - @backstage/core-components@0.8.7-next.1 + - @backstage/plugin-catalog-react@0.6.13-next.1 + - @backstage/plugin-catalog@0.7.11-next.1 + +## 0.13.2-next.0 + +### Patch Changes + +- 359c31e31d: Added support for documentation using the raw `` tag to point to relative resources like audio or video files. +- Updated dependencies + - @backstage/core-components@0.8.7-next.0 + - @backstage/integration-react@0.1.20-next.0 + - @backstage/plugin-catalog@0.7.11-next.0 + - @backstage/plugin-catalog-react@0.6.13-next.0 + - @backstage/plugin-search@0.6.1-next.0 + +## 0.13.1 + +### Patch Changes + +- bdc53553eb: chore(deps): bump `react-text-truncate` from 0.16.0 to 0.17.0 +- a64f99f734: Code snippets now include a "copy to clipboard" button. +- Updated dependencies + - @backstage/core-components@0.8.6 + - @backstage/plugin-search@0.6.0 + - @backstage/plugin-catalog@0.7.10 + +## 0.13.0 + +### Minor Changes + +- aecfe4f403: Make `TechDocsClient` and `TechDocsStorageClient` use the `FetchApi`. You now + need to pass in an instance of that API when constructing the client, if you + create a custom instance in your app. + + If you are replacing the factory: + + ```diff + +import { fetchApiRef } from '@backstage/core-plugin-api'; + + createApiFactory({ + api: techdocsStorageApiRef, + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + identityApi: identityApiRef, + + fetchApi: fetchApiRef, + }, + factory: ({ + configApi, + discoveryApi, + identityApi, + + fetchApi, + }) => + new TechDocsStorageClient({ + configApi, + discoveryApi, + identityApi, + + fetchApi, + }), + }), + createApiFactory({ + api: techdocsApiRef, + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + - identityApi: identityApiRef, + + fetchApi: fetchApiRef, + }, + factory: ({ + configApi, + discoveryApi, + - identityApi, + + fetchApi, + }) => + new TechDocsClient({ + configApi, + discoveryApi, + - identityApi, + + fetchApi, + }), + }), + ``` + + If instantiating directly: + + ```diff + +import { fetchApiRef } from '@backstage/core-plugin-api'; + + +const fetchApi = useApi(fetchApiRef); + const storageClient = new TechDocsStorageClient({ + configApi, + discoveryApi, + identityApi, + + fetchApi, + }); + const techdocsClient = new TechDocsClient({ + configApi, + discoveryApi, + - identityApi, + + fetchApi, + }), + ``` + +### Patch Changes + +- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. +- 29710c91c2: use lighter color for block quotes and horizontal rulers +- Updated dependencies + - @backstage/core-components@0.8.5 + - @backstage/integration@0.7.2 + - @backstage/plugin-search@0.5.6 + - @backstage/core-plugin-api@0.6.0 + - @backstage/plugin-catalog@0.7.9 + - @backstage/plugin-catalog-react@0.6.12 + - @backstage/config@0.1.13 + - @backstage/catalog-model@0.9.10 + - @backstage/integration-react@0.1.19 + +## 0.12.15-next.0 + +### Patch Changes + +- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. +- 29710c91c2: use lighter color for block quotes and horizontal rulers +- Updated dependencies + - @backstage/core-components@0.8.5-next.0 + - @backstage/core-plugin-api@0.6.0-next.0 + - @backstage/plugin-catalog@0.7.9-next.0 + - @backstage/config@0.1.13-next.0 + - @backstage/plugin-catalog-react@0.6.12-next.0 + - @backstage/plugin-search@0.5.6-next.0 + - @backstage/catalog-model@0.9.10-next.0 + - @backstage/integration-react@0.1.19-next.0 + - @backstage/integration@0.7.2-next.0 + +## 0.12.14 + +### Patch Changes + +- 5333451def: Cleaned up API exports +- 1628ca3f49: Fix an issue where the TechDocs sidebar is hidden when the Backstage sidebar is pinned at smaller screen sizes +- Updated dependencies + - @backstage/config@0.1.12 + - @backstage/integration@0.7.1 + - @backstage/core-components@0.8.4 + - @backstage/core-plugin-api@0.5.0 + - @backstage/plugin-catalog-react@0.6.11 + - @backstage/errors@0.2.0 + - @backstage/catalog-model@0.9.9 + - @backstage/integration-react@0.1.18 + - @backstage/plugin-catalog@0.7.8 + - @backstage/plugin-search@0.5.5 + +## 0.12.13 + +### Patch Changes + +- fe9de6c25b: Adds support for opening internal Techdocs links in a new tab with CTRL+Click or CMD+Click +- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. +- e0271456d8: Updated Techdocs footer navigation to dynamically resize to the width of the dom, resolving an issue where a pinned sidebar causes navigation to go off of the screen +- Updated dependencies + - @backstage/plugin-search@0.5.4 + - @backstage/core-plugin-api@0.4.1 + - @backstage/plugin-catalog-react@0.6.10 + - @backstage/core-components@0.8.3 + - @backstage/plugin-catalog@0.7.7 + +## 0.12.12 + +### Patch Changes + +- aa8f764a3e: Add the techdocs.sanitizer.allowedIframeHosts config. + This config allows all iframes which have the host of the attribute src in the 'allowedIframehosts' list to be displayed in the documentation. +- Updated dependencies + - @backstage/plugin-search@0.5.3 + - @backstage/plugin-catalog@0.7.6 + - @backstage/plugin-catalog-react@0.6.9 + - @backstage/integration@0.7.0 + - @backstage/integration-react@0.1.17 + +## 0.12.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search@0.5.2 + - @backstage/core-plugin-api@0.4.0 + - @backstage/plugin-catalog-react@0.6.8 + - @backstage/core-components@0.8.2 + - @backstage/plugin-catalog@0.7.5 + - @backstage/integration-react@0.1.16 + +## 0.12.10 + +### Patch Changes + +- e7cce2b603: Fix issue where assets weren't being fetched from the correct URL path for doc URLs without trailing slashes +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/catalog-model@0.9.8 + - @backstage/plugin-catalog-react@0.6.7 + +## 0.12.9 + +### Patch Changes + +- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. +- d90dad84b0: Switch to using `LogViewer` component from `@backstage/core-components` to display build logs. +- 3421826ca8: The problem of lowercase entity triplets which causes docs to not load on entity page is fixed. +- Updated dependencies + - @backstage/core-components@0.8.0 + - @backstage/core-plugin-api@0.3.0 + - @backstage/plugin-catalog@0.7.4 + - @backstage/integration-react@0.1.15 + - @backstage/plugin-catalog-react@0.6.5 + - @backstage/plugin-search@0.5.1 + +## 0.12.8 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@0.6.10 + - @backstage/core-components@0.7.6 + - @backstage/theme@0.2.14 + - @backstage/core-plugin-api@0.2.2 + - @backstage/plugin-search@0.5.0 + +## 0.12.7 + +### Patch Changes + +- bab752e2b3: Change default port of backend from 7000 to 7007. + + This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start. + + You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values: + + backend: + listen: 0.0.0.0:7123 + baseUrl: http://localhost:7123 + + More information can be found here: + +- Updated dependencies + - @backstage/errors@0.1.5 + - @backstage/core-plugin-api@0.2.1 + - @backstage/core-components@0.7.5 + +## 0.12.6 + +### Patch Changes + +- a125278b81: Refactor out the deprecated path and icon from RouteRefs +- c1858c4cf9: Fixed entity triplet case handling for certain locales. +- f7703981a9: Use a better checkbox rendering in a task list. +- e266687580: Updates reader component used to display techdocs documentation. A previous change made this component not usable out of a page which don't have entityRef in url parameters. Reader component EntityRef parameter is now used instead of url parameters. Techdocs documentation component can now be used in our custom pages. +- Updated dependencies + - @backstage/plugin-catalog@0.7.3 + - @backstage/catalog-model@0.9.7 + - @backstage/plugin-catalog-react@0.6.4 + - @backstage/plugin-search@0.4.18 + - @backstage/core-components@0.7.4 + - @backstage/core-plugin-api@0.2.0 + - @backstage/integration-react@0.1.14 + +## 0.12.5 + +### Patch Changes + +- fe5738fe1c: Lazy load `LazyLog` as it is rarely used. +- 53c9ad7e04: Update font weight for headings in TechDocs +- Updated dependencies + - @backstage/core-components@0.7.3 + - @backstage/theme@0.2.13 + - @backstage/plugin-search@0.4.17 + - @backstage/core-plugin-api@0.1.13 + - @backstage/plugin-catalog-react@0.6.3 + +## 0.12.4 + +### Patch Changes + +- a9a8c6f7c5: Reader will now scroll to the top of the page when navigating between pages +- 106a5dc3ad: Restore original casing for `kind`, `namespace` and `name` in `DefaultTechDocsCollator`. +- Updated dependencies + - @backstage/config@0.1.11 + - @backstage/theme@0.2.12 + - @backstage/errors@0.1.4 + - @backstage/integration@0.6.9 + - @backstage/core-components@0.7.2 + - @backstage/integration-react@0.1.13 + - @backstage/plugin-catalog-react@0.6.2 + - @backstage/catalog-model@0.9.6 + - @backstage/plugin-search@0.4.16 + - @backstage/core-plugin-api@0.1.12 + +## 0.12.3 + +### Patch Changes + +- ba5b75ed2f: Add `` as an alternative to `` that + shows a grid of card instead of table. + + Extend `` to display the entity title of the entity instead of the + name if available. + +- 177401b571: Display entity title (if defined) in titles of TechDocs search results + +- cdf8ca6111: Only replace the shadow dom if the content is changed to avoid a flickering UI. + +- Updated dependencies + - @backstage/core-components@0.7.1 + - @backstage/errors@0.1.3 + - @backstage/core-plugin-api@0.1.11 + - @backstage/plugin-catalog@0.7.2 + - @backstage/plugin-catalog-react@0.6.1 + - @backstage/catalog-model@0.9.5 + +## 0.12.2 + +### Patch Changes + +- 76fef740fe: Refactored `` component internals to support future extensibility. +- Updated dependencies + - @backstage/plugin-catalog-react@0.6.0 + - @backstage/plugin-catalog@0.7.1 + - @backstage/integration@0.6.8 + - @backstage/core-components@0.7.0 + - @backstage/theme@0.2.11 + - @backstage/plugin-search@0.4.15 + - @backstage/integration-react@0.1.12 + +## 0.12.1 + +### Patch Changes + +- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. +- Updated dependencies + - @backstage/core-components@0.6.1 + - @backstage/core-plugin-api@0.1.10 + - @backstage/plugin-catalog@0.7.0 + - @backstage/plugin-catalog-react@0.5.2 + - @backstage/catalog-model@0.9.4 + - @backstage/integration@0.6.7 + - @backstage/plugin-search@0.4.14 + +## 0.12.0 + +### Minor Changes + +- 82bb0842a3: Adds support for being able to customize and compose your TechDocs reader page in the App. + + You can likely upgrade to this version without issue. If, however, you have + imported the `` component in your custom code, the name of a property + has changed. You will need to make the following change anywhere you use it: + + ```diff + - + + + ``` + +### Patch Changes + +- 79ebee7a6b: Add "data-testid" for e2e tests and fix techdocs entity not found error. +- 3df2e8532b: Fixed the URL for the "Click to copy documentation link to clipboard" action +- 0a8bec0877: Added a check for the TechDocs annotation on the entity +- Updated dependencies + - @backstage/integration@0.6.6 + - @backstage/core-plugin-api@0.1.9 + - @backstage/core-components@0.6.0 + - @backstage/integration-react@0.1.11 + - @backstage/plugin-catalog@0.6.17 + - @backstage/plugin-catalog-react@0.5.1 + - @backstage/plugin-search@0.4.13 + +## 0.11.3 + +### Patch Changes + +- be13dfe61a: Make techdocs context search bar width adjust on smaller screens. +- Updated dependencies + - @backstage/core-components@0.5.0 + - @backstage/integration@0.6.5 + - @backstage/plugin-catalog@0.6.16 + - @backstage/plugin-catalog-react@0.5.0 + - @backstage/catalog-model@0.9.3 + - @backstage/config@0.1.10 + - @backstage/integration-react@0.1.10 + - @backstage/plugin-search@0.4.12 + +## 0.11.2 + +### Patch Changes + +- 1d346ba903: Modify TechDocsCollator to be aware of new TechDocs URL pattern. Modify tech docs in context search to use correct casing when creating initial filter. +- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. +- 96fef17a18: Upgrade git-parse-url to v11.6.0 +- Updated dependencies + - @backstage/core-components@0.4.2 + - @backstage/integration@0.6.4 + - @backstage/integration-react@0.1.9 + - @backstage/plugin-catalog@0.6.15 + - @backstage/plugin-catalog-react@0.4.6 + - @backstage/plugin-search@0.4.11 + - @backstage/core-plugin-api@0.1.8 + +## 0.11.1 + +### Patch Changes + +- 30ed662a3: Adding in-context search to TechDocs Reader component. Using existing search-backend to query for indexed search results scoped into a specific entity's techdocs. Needs TechDocsCollator enabled on the backend to work. + + Adding extra information to indexed tech docs documents for search. + +- 434dfc5d4: Display [metadata.title](https://backstage.io/docs/features/software-catalog/descriptor-format#title-optional) for components on the TechDocs homepage, if defined; otherwise fall back to `metadata.name` as displayed before. + +- Updated dependencies + - @backstage/plugin-catalog-react@0.4.5 + - @backstage/integration@0.6.3 + - @backstage/core-components@0.4.0 + - @backstage/plugin-catalog@0.6.14 + - @backstage/plugin-search@0.4.9 + - @backstage/catalog-model@0.9.1 + - @backstage/integration-react@0.1.8 + +## 0.11.0 + +### Minor Changes + +- c772d9a84: TechDocs sites can now be accessed using paths containing entity triplets of + any case (e.g. `/docs/namespace/KIND/name` or `/docs/namespace/kind/name`). + + If you do not use an external storage provider for serving TechDocs, this is a + transparent change and no action is required from you. + + If you _do_ use an external storage provider for serving TechDocs (one of\* GCS, + AWS S3, or Azure Blob Storage), you must run a migration command against your + storage provider before updating. + + [A migration guide is available here](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-migrate-from-techdocs-alpha-to-beta). + + - (\*) We're seeking help from the community to bring OpenStack Swift support + [to feature parity](https://github.com/backstage/backstage/issues/6763) with the above. + +- 787bc0826: The TechDocs plugin has completed the migration to the Composability API. In + order to update to this version, please ensure you've made all necessary + changes to your `App.tsx` file as outlined in the [create-app changelog][cacl]. + + [cacl]: https://github.com/backstage/backstage/blob/master/packages/create-app/CHANGELOG.md + +### Patch Changes + +- 90c68a2ca: Fix Techdocs feedback icon link for GitHub URLs +- Updated dependencies + - @backstage/plugin-catalog@0.6.13 + - @backstage/plugin-catalog-react@0.4.4 + - @backstage/core-components@0.3.3 + - @backstage/integration@0.6.2 + - @backstage/config@0.1.8 + +## 0.10.4 + +### Patch Changes + +- a440d3b38: Expose a new composable `TechDocsIndexPage` and a `DefaultTechDocsHome` with support for starring docs and filtering on owned, starred, owner, and tags. + + You can migrate to the new UI view by making the following changes in your `App.tsx`: + + ```diff + - } /> + + }> + + + + + + } + + /> + ``` + +- 56c773909: Switched `@types/react` dependency to request `*` rather than a specific version. + +- 8a3e46591: Switch `EventSource` implementation with header support from a Node.js API-based one to an XHR-based one. + +- Updated dependencies + - @backstage/integration@0.6.0 + - @backstage/core-components@0.3.1 + - @backstage/core-plugin-api@0.1.6 + - @backstage/plugin-catalog@0.6.11 + - @backstage/plugin-catalog-react@0.4.2 + - @backstage/integration-react@0.1.7 + +## 0.10.3 + +### Patch Changes + +- 260c053b9: Fix All Material UI Warnings +- db58cf06c: Avoid sanitize safe links in the header of document pages. +- 1d65bd490: Fix Techdocs feedback icon link for GitLab URLs with subgroup(s) in path +- Updated dependencies + - @backstage/core-components@0.3.0 + - @backstage/config@0.1.6 + - @backstage/core-plugin-api@0.1.5 + - @backstage/integration@0.5.9 + - @backstage/integration-react@0.1.6 + - @backstage/plugin-catalog-react@0.4.1 + +## 0.10.2 + +### Patch Changes + +- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. + - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` + - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. + - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` + - `onChangePage` has been renamed to `onPageChange` + - Migration guide is here: +- 11c370af2: Optimize load times by only fetching entities with the `backstage.io/techdocs-ref` annotation +- 2b1ac002d: TechDocs now uses a "safe by default" sanitization library, rather than relying on its own, hard-coded list of allowable tags and attributes. +- Updated dependencies + - @backstage/core-components@0.2.0 + - @backstage/plugin-catalog-react@0.4.0 + - @backstage/core-plugin-api@0.1.4 + - @backstage/integration-react@0.1.5 + - @backstage/theme@0.2.9 + +## 0.10.1 + +### Patch Changes + +- 9266b80ab: Add search list item to display tech docs search results + +- 03bf17e9b: Improve the responsiveness of the EntityPage UI. With this the Header component should scale with the screen size & wrapping should not cause overflowing/blocking of links. Additionally enforce the Pages using the Grid Layout to use it across all screen sizes & to wrap as intended. + + To benefit from the improved responsive layout, the `EntityPage` in existing Backstage applications should be updated to set the `xs` column size on each grid item in the page, as this does not default. For example: + + ```diff + - + + + ``` + +- 378cc6a54: Only update the `path` when the content is updated. + If content and path are updated independently, the frontend rendering is triggered twice on each navigation: Once for the `path` change (with the old content) and once for the new content. + This might result in a flickering rendering that is caused by the async frontend preprocessing, and the fact that replacing the shadow dom content is expensive. + +- 214e7c52d: Refactor the techdocs transformers to return `Promise`s and await all transformations. + +- e35b13afa: Handle error responses in `getTechDocsMetadata` and `getEntityMetadata` such that `` doesn't throw errors. + +- Updated dependencies + - @backstage/core-components@0.1.6 + - @backstage/plugin-catalog-react@0.3.1 + +## 0.10.0 + +### Minor Changes + +- 94a54dd47: Added a `migrateDocsCase()` method to TechDocs publishers, along with + implementations for AWS, Azure, and GCS. + + This change is in support of a future update to TechDocs that will allow for + case-insensitive entity triplet URL access to documentation pages which will + require a migration of existing documentation objects in external storage + solutions. + + See [#4367](https://github.com/backstage/backstage/issues/4367) for details. + +### Patch Changes + +- 537c37b0f: Fix displaying owned documents list by fetching associated entity relations +- 136a91974: Show a "Refresh" button to if the content is stale. + This removes the need to do a full page-reload to display more recent TechDocs content. +- f1200f44c: Rewrite the `/sync/:namespace/:kind/:name` endpoint to support an event-stream as response. + This change allows the sync process to take longer than a normal HTTP timeout. + The stream also emits log events, so the caller can follow the build process in the frontend. +- 3af126cdd: Provide a Drawer component to follow a running build. + This can be used to debug the rendering and get build logs in case an error occurs. +- 2a4a3b32d: Techdocs: fix sidebars not adjusting position automatically +- Updated dependencies + - @backstage/plugin-catalog-react@0.3.0 + +## 0.9.9 + +### Patch Changes + +- 0172d3424: Fixed bug preventing scroll bar from showing up on code blocks in a TechDocs site. +- Updated dependencies + - @backstage/integration@0.5.8 + - @backstage/core-components@0.1.5 + - @backstage/catalog-model@0.9.0 + - @backstage/plugin-catalog-react@0.2.6 + +## 0.9.8 + +### Patch Changes + +- 99a2873c7: Include cookies when making fetch requests for SVG from techdocs plugin +- a444c7431: Filter fetched entity fields to optimize loading techdocs list +- Updated dependencies + - @backstage/plugin-catalog-react@0.2.5 + - @backstage/core-components@0.1.4 + - @backstage/integration@0.5.7 + +## 0.9.7 + +### Patch Changes + +- aefd54da6: Fix the overlapping between the sidebar and the tabs navigation when enabled in mkdocs (features: navigation.tabs) +- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. +- 1dfec7a2a: Refactor the implicit logic from `` into an explicit state machine. This resolves some state synchronization issues when content is refreshed or rebuilt in the backend. +- Updated dependencies + - @backstage/core-plugin-api@0.1.3 + - @backstage/catalog-model@0.8.4 + - @backstage/integration-react@0.1.4 + - @backstage/plugin-catalog-react@0.2.4 + +## 0.9.6 + +### Patch Changes + +- 938aee2fb: Fix the link to the documentation page when no owned documents are displayed +- 2e1fbe203: Do not add trailing slash for .html pages during doc links rewriting +- 9b57fda8b: Fixes a bug that could prevent some externally hosted images (like icons or + build badges) from rendering within TechDocs documentation. +- 667656c8b: Adding support for user owned document filter for TechDocs custom Homepage +- Updated dependencies + - @backstage/plugin-catalog-react@0.2.3 + - @backstage/catalog-model@0.8.3 + - @backstage/core@0.7.13 + +## 0.9.5 + +### Patch Changes + +- aad98c544: Fixes multiple XSS and sanitization bypass vulnerabilities in TechDocs. +- Updated dependencies [e7c5e4b30] +- Updated dependencies [ebe802bc4] +- Updated dependencies [49d7ec169] +- Updated dependencies [1cf1d351f] +- Updated dependencies [deaba2e13] +- Updated dependencies [8e919a6f8] + - @backstage/theme@0.2.8 + - @backstage/catalog-model@0.8.1 + - @backstage/integration@0.5.5 + - @backstage/core@0.7.12 + - @backstage/plugin-catalog-react@0.2.1 + +## 0.9.4 + +### Patch Changes + +- 4ea9df9d3: Set admonition font size to 1rem in TechDocs to align with the rest of the document's font sizes. + Fixes #5448 and #5541. +- bf805b467: Fixes #5529, a bug that prevented TechDocs from rendering pages containing malformed links. +- 203ce6f6f: TechDocs now respects the `download` attribute on anchor tags in generated + markup, allowing documentation authors to bundle downloadable files with their + documentation. +- Updated dependencies [0fd4ea443] +- Updated dependencies [add62a455] +- Updated dependencies [cc592248b] +- Updated dependencies [17c497b81] +- Updated dependencies [704875e26] + - @backstage/integration@0.5.4 + - @backstage/catalog-model@0.8.0 + - @backstage/core@0.7.11 + - @backstage/plugin-catalog-react@0.2.0 + +## 0.9.3 + +### Patch Changes + +- 65e6c4541: Remove circular dependencies +- a62cfe068: Bug fix on sidebar position when Tab-Bar is enabled +- 35e091604: Handle URLs with a `#hash` correctly when rewriting link URLs. +- Updated dependencies [f7f7783a3] +- Updated dependencies [65e6c4541] +- Updated dependencies [68fdbf014] +- Updated dependencies [5da6a561d] + - @backstage/catalog-model@0.7.10 + - @backstage/core@0.7.10 + - @backstage/integration@0.5.3 + +## 0.9.2 + +### Patch Changes + +- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 +- 675a569a9: chore: bump `react-use` dependency in all packages +- Updated dependencies [062bbf90f] +- Updated dependencies [10c008a3a] +- Updated dependencies [889d89b6e] +- Updated dependencies [16be1d093] +- Updated dependencies [3f988cb63] +- Updated dependencies [675a569a9] + - @backstage/core@0.7.9 + - @backstage/integration-react@0.1.2 + - @backstage/plugin-catalog-react@0.1.6 + - @backstage/catalog-model@0.7.9 + +## 0.9.1 + +### Patch Changes + +- 2e05277e0: Fix navigation in a page using the table of contents. +- 4075c6367: Make git config optional for techdocs feedback links +- Updated dependencies [38ca05168] +- Updated dependencies [f65adcde7] +- Updated dependencies [81c54d1f2] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] + - @backstage/integration@0.5.2 + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-react@0.1.5 + - @backstage/theme@0.2.7 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + +## 0.9.0 + +### Minor Changes + +- 21fddf452: Make `techdocsStorageApiRef` and `techdocsApiRef` use interfaces instead of the + actual implementation classes. + + This renames the classes `TechDocsApi` to `TechDocsClient` and `TechDocsStorageApi` + to `TechDocsStorageClient` and renames the interfaces `TechDocs` to `TechDocsApi` + and `TechDocsStorage` to `TechDocsStorageApi` to comply the pattern elsewhere in + the project. This also fixes the types returned by some methods on those + interfaces. + +### Patch Changes + +- 6fbd7beca: Use `EntityRefLink` in header and use relations to reference the owner of the + document. +- 15cbe6815: Fix TechDocs landing page table wrong copied link +- 39bdaa004: Add customization and exportable components for TechDocs landing page +- cb8c848a3: Disable color transitions on links to avoid issues in dark mode. +- 17915e29b: Rework state management to avoid rendering multiple while navigating between pages. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + +## 0.8.0 + +### Minor Changes + +- ac6025f63: Add feedback link icon in Techdocs Reader that directs to GitLab or GitHub repo issue page with pre-filled title and source link. + For link to appear, requires `repo_url` and `edit_uri` to be filled in mkdocs.yml, as per . An `edit_uri` will need to be specified for self-hosted GitLab/GitHub instances with a different host name. + To identify issue URL format as GitHub or GitLab, the host name of source in `repo_url` is checked if it contains `gitlab` or `github`. Alternately this is determined by matching to `host` values from `integrations` in app-config.yaml. + +### Patch Changes + +- e292e393f: Add a test id to the shadow root element of the Reader to access it easily in e2e tests +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + +## 0.7.2 + +### Patch Changes + +- fef852ecd: Reworked the TechDocs plugin to support using the configured company name instead of + 'Backstage' in the page title. +- 18f7345a6: Add borders to TechDocs tables and increase font size. Fixes #5264 and #5276. +- Updated dependencies [bb5055aee] +- Updated dependencies [d0d1c2f7b] +- Updated dependencies [5d0740563] +- Updated dependencies [5cafcf452] +- Updated dependencies [86a95ba67] +- Updated dependencies [e27cb6c45] + - @backstage/catalog-model@0.7.7 + - @backstage/core@0.7.5 + +## 0.7.1 + +### Patch Changes + +- bebd1c4fe: Remove the `@backstage/techdocs-common` dependency to not pull in backend config schemas in the frontend. +- Updated dependencies [9f48b548c] +- Updated dependencies [8488a1a96] + - @backstage/plugin-catalog-react@0.1.4 + - @backstage/catalog-model@0.7.5 + +## 0.7.0 + +### Minor Changes + +- aaeb7ecf3: When newer documentation available but not built, show older documentation while async building newer + TechDocs backend: /sync endpoint added to support above, returns immediate success if docs don't need a build, returns delayed success after build if needed + TechDocs backend: /docs endpoint removed as frontend can directly request to techdocs.storageUrl or /static/docs +- 3139f83af: Add sticky sidebars and footer navigation links to TechDocs Reader + +### Patch Changes + +- ea9d977e7: Introduce workaround for admonition icons of MkDocs. +- 2aab54319: TechDocs: links at sidebar and bottom reset scroll position to top +- Updated dependencies [01ccef4c7] +- Updated dependencies [fcc3ada24] +- Updated dependencies [4618774ff] +- Updated dependencies [df59930b3] + - @backstage/plugin-catalog-react@0.1.3 + - @backstage/core@0.7.3 + - @backstage/theme@0.2.5 + +## 0.6.2 + +### Patch Changes + +- 83bfc98a3: On TechDocs page header, change the breadcrumbs link to be static and point to TechDocs homepage. +- e7baa0d2e: Separate techdocs-backend and frontend config schema declarations +- c8b54c370: Extended TechDocs HomePage with owned documents +- Updated dependencies [0434853a5] +- Updated dependencies [8686eb38c] +- Updated dependencies [9ca0e4009] +- Updated dependencies [34ff49b0f] +- Updated dependencies [8686eb38c] +- Updated dependencies [424742dc1] +- Updated dependencies [4e0b5055a] + - @backstage/config@0.1.4 + - @backstage/core@0.7.2 + - @backstage/plugin-catalog-react@0.1.2 + - @backstage/techdocs-common@0.4.5 + - @backstage/test-utils@0.1.9 + +## 0.6.1 + +### Patch Changes + +- aa095e469: OpenStack Swift publisher added for tech-docs. +- 2089de76b: Make use of the new core `ItemCardGrid` and `ItemCardHeader` instead of the deprecated `ItemCard`. +- 868e4cdf2: - Adds a link to the owner entity + - Corrects the link to the component which includes the namespace +- ca4a904f6: Add an optional configuration option for setting the url endpoint for AWS S3 publisher: `techdocs.publisher.awsS3.endpoint` +- Updated dependencies [d7245b733] +- Updated dependencies [0b42fff22] +- Updated dependencies [0b42fff22] +- Updated dependencies [2ef5bc7ea] +- Updated dependencies [ff4d666ab] +- Updated dependencies [aa095e469] +- Updated dependencies [2089de76b] +- Updated dependencies [dc1fc92c8] +- Updated dependencies [bc46435f5] +- Updated dependencies [a501128db] +- Updated dependencies [ca4a904f6] + - @backstage/techdocs-common@0.4.4 + - @backstage/catalog-model@0.7.4 + - @backstage/core@0.7.1 + - @backstage/theme@0.2.4 + +## 0.6.0 + +### Minor Changes + +- 813c6a4f2: Add authorization header on techdocs api requests. Breaking change as clients now needs the Identity API. + +### Patch Changes + +- Updated dependencies [12d8f27a6] +- Updated dependencies [f43192207] +- Updated dependencies [40c0fdbaa] +- Updated dependencies [2a271d89e] +- Updated dependencies [bece09057] +- Updated dependencies [169f48deb] +- Updated dependencies [8a1566719] +- Updated dependencies [9d455f69a] +- Updated dependencies [4c049a1a1] +- Updated dependencies [02816ecd7] +- Updated dependencies [61299519f] + - @backstage/catalog-model@0.7.3 + - @backstage/techdocs-common@0.4.3 + - @backstage/core@0.7.0 + - @backstage/plugin-catalog-react@0.1.1 + +## 0.5.8 + +### Patch Changes + +- f37992797: Got rid of some `attr` and cleaned up a bit in the TechDocs config schema. +- 2499f6cde: Add support for assuming role in AWS integrations +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [dc12852c9] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2499f6cde] +- Updated dependencies [a1f5e6545] +- Updated dependencies [1e4ddd71d] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/test-utils@0.1.8 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + - @backstage/techdocs-common@0.4.2 + - @backstage/config@0.1.3 + +## 0.5.7 + +### Patch Changes + +- Updated dependencies [fd3f2a8c0] +- Updated dependencies [fb28da212] +- Updated dependencies [d34d26125] +- Updated dependencies [0af242b6d] +- Updated dependencies [f4c2bcf54] +- Updated dependencies [10a0124e0] +- Updated dependencies [07e226872] +- Updated dependencies [26e143e60] +- Updated dependencies [c6655413d] +- Updated dependencies [44414239f] +- Updated dependencies [b0a41c707] +- Updated dependencies [f62e7abe5] +- Updated dependencies [96f378d10] +- Updated dependencies [688b73110] + - @backstage/core@0.6.2 + - @backstage/techdocs-common@0.4.1 + - @backstage/plugin-catalog-react@0.0.4 + +## 0.5.6 + +### Patch Changes + +- f5e564cd6: Improve display of error messages +- 41af18227: Migrated to new composability API, exporting the plugin instance as `techdocsPlugin`, the top-level page as `TechdocsPage`, and the entity content as `EntityTechdocsContent`. +- 8f3443427: Enhance API calls to support trapping 500 errors from techdocs-backend +- Updated dependencies [77ad0003a] +- Updated dependencies [b51ee6ece] +- Updated dependencies [19d354c78] +- Updated dependencies [08142b256] +- Updated dependencies [08142b256] +- Updated dependencies [b51ee6ece] + - @backstage/techdocs-common@0.4.0 + - @backstage/test-utils@0.1.7 + - @backstage/plugin-catalog-react@0.0.3 + - @backstage/core@0.6.1 + +## 0.5.5 + +### Patch Changes + +- 5fa3bdb55: Add `href` in addition to `onClick` to `ItemCard`. Ensure that the height of a + `ItemCard` with and without tags is equal. +- e44925723: `techdocs.requestUrl` and `techdocs.storageUrl` are now optional configs and the discovery API will be used to get the URL where techdocs plugin is hosted. +- 019fe39a0: Switch dependency from `@backstage/plugin-catalog` to `@backstage/plugin-catalog-react`. +- Updated dependencies [c777df180] +- Updated dependencies [12ece98cd] +- Updated dependencies [d82246867] +- Updated dependencies [7fc89bae2] +- Updated dependencies [c810082ae] +- Updated dependencies [5fa3bdb55] +- Updated dependencies [6e612ce25] +- Updated dependencies [e44925723] +- Updated dependencies [025e122c3] +- Updated dependencies [21e624ba9] +- Updated dependencies [da9f53c60] +- Updated dependencies [32c95605f] +- Updated dependencies [7881f2117] +- Updated dependencies [f0320190d] +- Updated dependencies [54c7d02f7] +- Updated dependencies [11cb5ef94] + - @backstage/techdocs-common@0.3.7 + - @backstage/core@0.6.0 + - @backstage/plugin-catalog-react@0.0.2 + - @backstage/theme@0.2.3 + - @backstage/catalog-model@0.7.1 + +## 0.5.4 + +### Patch Changes + +- a5e27d5c1: Create type for TechDocsMetadata (#3716) + + This change introduces a new type (TechDocsMetadata) in packages/techdocs-common. This type is then introduced in the endpoint response in techdocs-backend and in the api interface in techdocs (frontend). + +- Updated dependencies [def2307f3] + +- Updated dependencies [efd6ef753] + +- Updated dependencies [593632f07] + +- Updated dependencies [33846acfc] + +- Updated dependencies [a187b8ad0] + +- Updated dependencies [f04db53d7] + +- Updated dependencies [53c9c51f2] + +- Updated dependencies [a5e27d5c1] + +- Updated dependencies [a93f42213] + - @backstage/catalog-model@0.7.0 + - @backstage/core@0.5.0 + - @backstage/plugin-catalog@0.2.12 + - @backstage/techdocs-common@0.3.5 + +## 0.5.3 + +### Patch Changes + +- dbe4450c3: Google Cloud authentication in TechDocs has been improved. + + 1. `techdocs.publisher.googleGcs.credentials` is now optional. If it is missing, `GOOGLE_APPLICATION_CREDENTIALS` + environment variable (and some other methods) will be used to authenticate. + Read more here + + 2. `techdocs.publisher.googleGcs.projectId` is no longer used. You can remove it from your `app-config.yaml`. + +- a6f9dca0d: Remove dependency on `@backstage/core-api`. No plugin should ever depend on that package; it's an internal concern whose important bits are re-exported by `@backstage/core` which is the public facing dependency to use. + +- b3b9445df: AWS S3 authentication in TechDocs has been improved. + + 1. `techdocs.publisher.awsS3.bucketName` is now the only required config. `techdocs.publisher.awsS3.credentials` and `techdocs.publisher.awsS3.region` are optional. + + 2. If `techdocs.publisher.awsS3.credentials` and `techdocs.publisher.awsS3.region` are missing, the AWS environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_REGION` will be used. There are more better ways of setting up AWS authentication. Read the guide at + +- e5d12f705: Use `history.pushState` for hash link navigation. + +- Updated dependencies [68ad5af51] + +- Updated dependencies [f3b064e1c] + +- Updated dependencies [371f67ecd] + +- Updated dependencies [f1e74777a] + +- Updated dependencies [dbe4450c3] + +- Updated dependencies [c00488983] + +- Updated dependencies [265a7ab30] + +- Updated dependencies [5826d0973] + +- Updated dependencies [b3b9445df] + +- Updated dependencies [abbee6fff] + +- Updated dependencies [147fadcb9] + - @backstage/techdocs-common@0.3.3 + - @backstage/catalog-model@0.6.1 + - @backstage/plugin-catalog@0.2.11 + - @backstage/core@0.4.4 + +## 0.5.2 + +### Patch Changes + +- 359f9d2d8: Added configuration schema for the commonly used properties of techdocs and techdocs-backend plugins +- Updated dependencies [a08c32ced] +- Updated dependencies [7e0b8cac5] +- Updated dependencies [8804e8981] +- Updated dependencies [87c0c53c2] +- Updated dependencies [86c3c652a] +- Updated dependencies [27f2af935] + - @backstage/core-api@0.2.8 + - @backstage/core@0.4.3 + - @backstage/plugin-catalog@0.2.9 + - @backstage/techdocs-common@0.3.1 + +## 0.5.1 + +### Patch Changes + +- Updated dependencies [d681db2b5] +- Updated dependencies [1dc445e89] +- Updated dependencies [342270e4d] +- Updated dependencies [1dc445e89] +- Updated dependencies [a8573e53b] + - @backstage/core-api@0.2.7 + - @backstage/core@0.4.2 + - @backstage/test-utils@0.1.6 + - @backstage/plugin-catalog@0.2.8 + - @backstage/techdocs-common@0.3.0 + +## 0.5.0 + +### Minor Changes + +- dae4f3983: _Breaking changes_ + + 1. Added option to use Google Cloud Storage as a choice to store the static generated files for TechDocs. + It can be configured using `techdocs.publisher.type` option in `app-config.yaml`. + Step-by-step guide to configure GCS is available here + Set `techdocs.publisher.type` to `'local'` if you want to continue using local filesystem to store TechDocs files. + + 2. `techdocs.builder` is now required and can be set to `'local'` or `'external'`. (Set it to `'local'` for now, since CI/CD build + workflow for TechDocs will be available soon (in few weeks)). + If builder is set to 'local' and you open a TechDocs page, `techdocs-backend` will try to generate the docs, publish to storage and + show the generated docs afterwords. + If builder is set to `'external'`, `techdocs-backend` will only fetch the docs and will NOT try to generate and publish. In this case of `'external'`, + we assume that docs are being built in the CI/CD pipeline of the repository. + TechDocs will not assume a default value for `techdocs.builder`. It is better to explicitly define it in the `app-config.yaml`. + + 3. When configuring TechDocs in your backend, there is a difference in how a new publisher is created. + + --- const publisher = new LocalPublish(logger, discovery); + +++ const publisher = Publisher.fromConfig(config, logger, discovery); + + Based on the config `techdocs.publisher.type`, the publisher could be either Local publisher or Google Cloud Storage publisher. + + 4. `techdocs.storageUrl` is now a required config. Should be `http://localhost:7000/api/techdocs/static/docs` in most setups. + + 5. Parts of `@backstage/plugin-techdocs-backend` have been moved to a new package `@backstage/techdocs-common` to generate docs. Also to publish docs + to-and-fro between TechDocs and a storage (either local or external). However, a Backstage app does NOT need to import the `techdocs-common` package - + app should only import `@backstage/plugin-techdocs` and `@backstage/plugin-techdocs-backend`. + + _Patch changes_ + + 1. See all of TechDocs config options and its documentation + + 2. Logic about serving static files and metadata retrieval have been abstracted away from the router in `techdocs-backend` to the instance of publisher. + + 3. Removed Material UI Spinner from TechDocs header. Spinners cause unnecessary UX distraction. + Case 1 (when docs are built and are to be served): Spinners appear for a split second before the name of site shows up. This unnecessarily distracts eyes because spinners increase the size of the Header. A dot (.) would do fine. Definitely more can be done. + Case 2 (when docs are being generated): There is already a linear progress bar (which is recommended in Storybook). + +### Patch Changes + +- Updated dependencies [c911061b7] +- Updated dependencies [dae4f3983] +- Updated dependencies [8ef71ed32] +- Updated dependencies [0e6298f7e] +- Updated dependencies [7dd2ef7d1] +- Updated dependencies [ac3560b42] + - @backstage/catalog-model@0.6.0 + - @backstage/techdocs-common@0.2.0 + - @backstage/core@0.4.1 + - @backstage/core-api@0.2.6 + - @backstage/plugin-catalog@0.2.7 + +## 0.4.0 + +### Minor Changes + +- 87a33d2fe: Removed modifyCss transformer and moved the css to injectCss transformer + Fixed issue where some internal doc links would cause a reload of the page + +### Patch Changes + +- Updated dependencies [b6557c098] +- Updated dependencies [2527628e1] +- Updated dependencies [6011b7d3e] +- Updated dependencies [e1f4e24ef] +- Updated dependencies [1c69d4716] +- Updated dependencies [d8d5a17da] +- Updated dependencies [83b6e0c1f] +- Updated dependencies [1665ae8bb] +- Updated dependencies [04f26f88d] +- Updated dependencies [ff243ce96] + - @backstage/core-api@0.2.5 + - @backstage/core@0.4.0 + - @backstage/plugin-catalog@0.2.6 + - @backstage/test-utils@0.1.5 + - @backstage/catalog-model@0.5.0 + - @backstage/theme@0.2.2 + +## 0.3.1 + +### Patch Changes + +- da2ad65cb: Use type EntityName from catalog-model for entities +- Updated dependencies [b4488ddb0] +- Updated dependencies [08835a61d] +- Updated dependencies [a9fd599f7] +- Updated dependencies [bcc211a08] +- Updated dependencies [ebf37bbae] + - @backstage/core-api@0.2.4 + - @backstage/catalog-model@0.4.0 + - @backstage/plugin-catalog@0.2.5 + - @backstage/test-utils@0.1.4 + +## 0.3.0 + +### Minor Changes + +- 4b53294a6: - Use techdocs annotation to add repo_url if missing in mkdocs.yml. Having repo_url creates a Edit button on techdocs pages. + - techdocs-backend: API endpoint `/metadata/mkdocs/*` renamed to `/metadata/techdocs/*` + +### Patch Changes + +- Updated dependencies [6f70ed7a9] +- Updated dependencies [ab94c9542] +- Updated dependencies [2daf18e80] +- Updated dependencies [069cda35f] +- Updated dependencies [700a212b4] + - @backstage/plugin-catalog@0.2.4 + - @backstage/catalog-model@0.3.1 + - @backstage/core-api@0.2.3 + +## 0.2.3 + +### Patch Changes + +- Updated dependencies [475fc0aaa] +- Updated dependencies [1166fcc36] +- Updated dependencies [1185919f3] + - @backstage/core@0.3.2 + - @backstage/catalog-model@0.3.0 + - @backstage/plugin-catalog@0.2.3 + +## 0.2.2 + +### Patch Changes + +- 1722cb53c: Added configuration schema +- Updated dependencies [1722cb53c] +- Updated dependencies [8b7737d0b] + - @backstage/core@0.3.1 + - @backstage/plugin-catalog@0.2.2 + - @backstage/test-utils@0.1.3 + +## 0.2.1 + +### Patch Changes + +- Updated dependencies [c5bab94ab] +- Updated dependencies [7b37d65fd] +- Updated dependencies [4aca74e08] +- Updated dependencies [e8f69ba93] +- Updated dependencies [0c0798f08] +- Updated dependencies [0c0798f08] +- Updated dependencies [199237d2f] +- Updated dependencies [6627b626f] +- Updated dependencies [4577e377b] +- Updated dependencies [2d0bd1be7] + - @backstage/core-api@0.2.1 + - @backstage/core@0.3.0 + - @backstage/theme@0.2.1 + - @backstage/plugin-catalog@0.2.1 + +## 0.2.0 + +### Minor Changes + +- 28edd7d29: Create backend plugin through CLI +- 8351ad79b: Add a message if techdocs takes long time to load + + Fixes #2416. + + The UI after the change should look like this: + + ![techdocs-progress-bar](https://user-images.githubusercontent.com/33940798/94189286-296ac980-fec8-11ea-9051-1b3db938d12f.gif) + +### Patch Changes + +- 782f3b354: add test case for Progress component +- 57b54c8ed: While techdocs fetches site name and metadata for the component, the page title was displayed as '[object Object] | Backstage'. This has now been fixed to display the component ID if site name is not present or being fetched. +- Updated dependencies [28edd7d29] +- Updated dependencies [819a70229] +- Updated dependencies [3a4236570] +- Updated dependencies [ae5983387] +- Updated dependencies [0d4459c08] +- Updated dependencies [cbbd271c4] +- Updated dependencies [482b6313d] +- Updated dependencies [e0be86b6f] +- Updated dependencies [f70a52868] +- Updated dependencies [12b5fe940] +- Updated dependencies [368fd8243] +- Updated dependencies [1c60f716e] +- Updated dependencies [144c66d50] +- Updated dependencies [a768a07fb] +- Updated dependencies [b79017fd3] +- Updated dependencies [6d97d2d6f] +- Updated dependencies [5adfc005e] +- Updated dependencies [f0aa01bcc] +- Updated dependencies [0aecfded0] +- Updated dependencies [93a3fa3ae] +- Updated dependencies [782f3b354] +- Updated dependencies [8b9c8196f] +- Updated dependencies [2713f28f4] +- Updated dependencies [406015b0d] +- Updated dependencies [82759d3e4] +- Updated dependencies [60d40892c] +- Updated dependencies [ac8d5d5c7] +- Updated dependencies [2ebcfac8d] +- Updated dependencies [fa56f4615] +- Updated dependencies [ebca83d48] +- Updated dependencies [aca79334f] +- Updated dependencies [c0d5242a0] +- Updated dependencies [b3d57961c] +- Updated dependencies [0b956f21b] +- Updated dependencies [26e69ab1a] +- Updated dependencies [97c2cb19b] +- Updated dependencies [3beb5c9fc] +- Updated dependencies [cbab5bbf8] +- Updated dependencies [754e31db5] +- Updated dependencies [1611c6dbc] + - @backstage/plugin-catalog@0.2.0 + - @backstage/core-api@0.2.0 + - @backstage/core@0.2.0 + - @backstage/catalog-model@0.2.0 + - @backstage/theme@0.2.0 + - @backstage/test-utils@0.1.2 + +## @backstage/ui@0.9.0-next.1 + +### Minor Changes + +- 5c614ff: **BREAKING**: Migrated Checkbox component from Base UI to React Aria Components. + + API changes required: + + - `checked` → `isSelected` + - `defaultChecked` → `defaultSelected` + - `disabled` → `isDisabled` + - `required` → `isRequired` + - `label` prop removed - use `children` instead + - CSS: `bui-CheckboxLabel` class removed + - Data attribute: `data-checked` → `data-selected` + - Use without label is no longer supported + + Migration examples: + + Before: + + ```tsx + + ``` + + After: + + ```tsx + + Accept terms + + ``` + + Before: + + ```tsx + + ``` + + After: + + ```tsx + Option + ``` + + Before: + + ```tsx + + ``` + + After: + + ```tsx + + Accessible label + + ``` + +- b78fc45: **BREAKING**: Changed className prop behavior to augment default styles instead of being ignored or overriding them. + + Affected components: + + - Menu, MenuListBox, MenuAutocomplete, MenuAutocompleteListbox, MenuItem, MenuListBoxItem, MenuSection, MenuSeparator + - Switch + - Skeleton + - FieldLabel + - Header, HeaderToolbar + - HeaderPage + - Tabs, TabList, Tab, TabPanel + + If you were passing custom className values to any of these components that relied on the previous behavior, you may need to adjust your styles to account for the default classes now being applied alongside your custom classes. + +### Patch Changes + +- ff9f0c3: Enable tree-shaking of imports other than `*.css`. +- 1ef3ca4: Added new VisuallyHidden component for hiding content visually while keeping it accessible to screen readers. + +## @backstage/plugin-notifications-backend-module-email@0.3.16-next.0 + +# @backstage/plugin-notifications-backend-module-email + +## 0.3.15-next.0 + +### Patch Changes + +- 22a5362: Updated `AWS SES` client to version 2 to support `nodemailer` version 7. +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.21-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-notifications-common@0.1.2-next.0 + +## 0.3.14 + +### Patch Changes + +- b8cf31a: chore(deps): bump `nodemailer` from 6.9.16 to 7.0.7 +- f5e0963: Removed unused dependencies +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-notifications-common@0.1.1 + - @backstage/plugin-notifications-node@0.2.20 + +## 0.3.14-next.1 + +### Patch Changes + +- b8cf31a: chore(deps): bump `nodemailer` from 6.9.16 to 7.0.7 +- f5e0963: Removed unused dependencies + +## 0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-notifications-common@0.1.1-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-notifications-node@0.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## 0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/types@1.2.2 + - @backstage/plugin-notifications-node@0.2.19 + - @backstage/backend-plugin-api@1.4.3 + +## 0.3.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-notifications-node@0.2.19-next.1 + +## 0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-notifications-node@0.2.19-next.0 + +## 0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-notifications-node@0.2.18 + - @backstage/backend-plugin-api@1.4.2 + +## 0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-notifications-node@0.2.18-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.10 + +## 0.3.11 + +### Patch Changes + +- f92c9fc: Add optional config for `ses` mail options with `sourceArn`, `fromArn`, `configurationSetName` +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-notifications-node@0.2.17 + +## 0.3.11-next.1 + +### Patch Changes + +- f92c9fc: Add optional config for `ses` mail options with `sourceArn`, `fromArn`, `configurationSetName` + +## 0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-notifications-common@0.0.10-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-notifications-node@0.2.17-next.0 + +## 0.3.10 + +### Patch Changes + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## 0.3.10-next.2 + +### Patch Changes + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.1 + +## 0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-notifications-node@0.2.16-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## 0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.0 + +## 0.3.9 + +### Patch Changes + +- aa3a63a: Enable the ability to configure the endpoint for the SES connection used in the notifications email module. This enables the configuration of alternate endpoints as required, for example for local testing or alternative stacks. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/integration-aws-node@0.1.16 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/plugin-notifications-node@0.2.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## 0.3.9-next.3 + +### Patch Changes + +- aa3a63a: Enable the ability to configure the endpoint for the SES connection used in the notifications email module. This enables the configuration of alternate endpoints as required, for example for local testing or alternative stacks. +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1-next.2 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.0-next.2 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.15-next.2 + +## 0.3.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-aws-node@0.1.16-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-notifications-node@0.2.15-next.1 + - @backstage/backend-plugin-api@1.3.1-next.1 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.0-next.1 + - @backstage/plugin-notifications-common@0.0.8 + +## 0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.0-next.1 + - @backstage/backend-plugin-api@1.3.1-next.1 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.15-next.1 + +## 0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/plugin-catalog-node@1.17.0-next.0 + - @backstage/backend-plugin-api@1.3.1-next.0 + - @backstage/plugin-notifications-node@0.2.15-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## 0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.16.3 + - @backstage/backend-plugin-api@1.3.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.14 + +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.16.3-next.0 + - @backstage/backend-plugin-api@1.2.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.13 + +## 0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-aws-node@0.1.15 + - @backstage/backend-plugin-api@1.2.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.16.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.13 + +## 0.3.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.1-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.16.1-next.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.13-next.2 + +## 0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.1-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.16.1-next.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.13-next.1 + +## 0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.16.1-next.0 + - @backstage/plugin-notifications-node@0.2.13-next.0 + +## 0.3.6 + +### Patch Changes + +- 6259aa9: Add transport for Azure Communication Service +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0 + - @backstage/plugin-catalog-node@1.16.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12 + +## 0.3.6-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.16.0-next.3 + - @backstage/backend-plugin-api@1.2.0-next.2 + - @backstage/plugin-notifications-node@0.2.12-next.2 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## 0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.16.0-next.2 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.1 + +## 0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.16.0-next.1 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.0 + +## 0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.0 + +## 0.3.5 + +### Patch Changes + +- bed5f35: Added more examples of the plugin configuration +- Updated dependencies + - @backstage/types@1.2.1 + - @backstage/backend-plugin-api@1.1.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/plugin-catalog-node@1.15.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.11 + +## 0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.1-next.0 + - @backstage/backend-plugin-api@1.1.1-next.1 + - @backstage/catalog-model@1.7.3-next.0 + - @backstage/config@1.3.2-next.0 + - @backstage/plugin-catalog-node@1.15.1-next.1 + - @backstage/integration-aws-node@0.1.15-next.0 + - @backstage/plugin-notifications-node@0.2.11-next.1 + - @backstage/catalog-client@1.9.1-next.0 + - @backstage/plugin-notifications-common@0.0.8-next.0 + +## 0.3.5-next.0 + +### Patch Changes + +- bed5f35: Added more examples of the plugin configuration +- Updated dependencies + - @backstage/backend-plugin-api@1.1.1-next.0 + - @backstage/catalog-client@1.9.0 + - @backstage/catalog-model@1.7.2 + - @backstage/config@1.3.1 + - @backstage/integration-aws-node@0.1.14 + - @backstage/types@1.2.0 + - @backstage/plugin-catalog-node@1.15.1-next.0 + - @backstage/plugin-notifications-common@0.0.7 + - @backstage/plugin-notifications-node@0.2.11-next.0 + +## 0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.1.0 + - @backstage/plugin-catalog-node@1.15.0 + - @backstage/catalog-client@1.9.0 + - @backstage/plugin-notifications-node@0.2.10 + - @backstage/catalog-model@1.7.2 + - @backstage/config@1.3.1 + - @backstage/integration-aws-node@0.1.14 + - @backstage/types@1.2.0 + - @backstage/plugin-notifications-common@0.0.7 + +## 0.3.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.1.0-next.2 + - @backstage/plugin-catalog-node@1.15.0-next.2 + - @backstage/plugin-notifications-node@0.2.10-next.2 + - @backstage/catalog-client@1.9.0-next.2 + - @backstage/catalog-model@1.7.2-next.0 + - @backstage/config@1.3.1-next.0 + - @backstage/integration-aws-node@0.1.14-next.0 + - @backstage/types@1.2.0 + - @backstage/plugin-notifications-common@0.0.7-next.0 + +## 0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.0-next.1 + - @backstage/catalog-client@1.9.0-next.1 + - @backstage/plugin-notifications-node@0.2.10-next.1 + - @backstage/backend-plugin-api@1.1.0-next.1 + - @backstage/catalog-model@1.7.1 + - @backstage/config@1.3.0 + - @backstage/integration-aws-node@0.1.13 + - @backstage/types@1.2.0 + - @backstage/plugin-notifications-common@0.0.6 + +## 0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.3-next.0 + - @backstage/catalog-client@1.8.1-next.0 + - @backstage/catalog-model@1.7.1 + - @backstage/config@1.3.0 + - @backstage/integration-aws-node@0.1.13 + - @backstage/types@1.2.0 + - @backstage/plugin-catalog-node@1.14.1-next.0 + - @backstage/plugin-notifications-common@0.0.6 + - @backstage/plugin-notifications-node@0.2.10-next.0 + +## 0.3.3 + +### Patch Changes + +- d52d7f9: Support ISO and ms string forms of durations in config too +- 5d74716: Remove unused backend-common dependency +- Updated dependencies + - @backstage/catalog-client@1.8.0 + - @backstage/config@1.3.0 + - @backstage/types@1.2.0 + - @backstage/integration-aws-node@0.1.13 + - @backstage/plugin-catalog-node@1.14.0 + - @backstage/backend-plugin-api@1.0.2 + - @backstage/plugin-notifications-common@0.0.6 + - @backstage/plugin-notifications-node@0.2.9 + - @backstage/catalog-model@1.7.1 + +## 0.3.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-aws-node@0.1.13-next.0 + - @backstage/backend-plugin-api@1.0.2-next.2 + - @backstage/catalog-client@1.8.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.14.0-next.2 + - @backstage/plugin-notifications-common@0.0.6-next.0 + - @backstage/plugin-notifications-node@0.2.9-next.3 + +## 0.3.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.8.0-next.1 + - @backstage/plugin-catalog-node@1.14.0-next.2 + - @backstage/plugin-notifications-node@0.2.9-next.2 + - @backstage/backend-plugin-api@1.0.2-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.6-next.0 + +## 0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.2-next.1 + - @backstage/catalog-client@1.8.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.14.0-next.1 + - @backstage/plugin-notifications-common@0.0.6-next.0 + - @backstage/plugin-notifications-node@0.2.9-next.1 + +## 0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.14.0-next.0 + - @backstage/plugin-notifications-common@0.0.6-next.0 + - @backstage/catalog-client@1.8.0-next.0 + - @backstage/backend-plugin-api@1.0.2-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-node@0.2.9-next.0 + +## 0.3.1 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.7 + - @backstage/plugin-catalog-node@1.13.1 + - @backstage/catalog-client@1.7.1 + - @backstage/backend-plugin-api@1.0.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.13.1-next.1 + - @backstage/catalog-client@1.7.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.7-next.1 + +## 0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.7-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6 + +## 0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.2 + +## 0.3.0-next.1 + +### Patch Changes + +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.1 + +## 0.3.0-next.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-notifications-node@0.2.6-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.2.0 + +### Minor Changes + +- def53a7: **BREAKING** Following `NotificationTemplateRenderer` methods now return a Promise and **must** be awaited: `getSubject`, `getText` and `getHtml`. + + Required changes and example usage: + + ```diff + import { notificationsEmailTemplateExtensionPoint } from '@backstage/plugin-notifications-backend-module-email'; + import { Notification } from '@backstage/plugin-notifications-common'; + +import { getNotificationSubject, getNotificationTextContent, getNotificationHtmlContent } from 'my-notification-processing-library` + export const notificationsModuleEmailDecorator = createBackendModule({ + pluginId: 'notifications', + moduleId: 'email.templates', + register(reg) { + reg.registerInit({ + deps: { + emailTemplates: notificationsEmailTemplateExtensionPoint, + }, + async init({ emailTemplates }) { + emailTemplates.setTemplateRenderer({ + - getSubject(notification) { + + async getSubject(notification) { + - return `New notification from ${notification.source}`; + + const subject = await getNotificationSubject(notification); + + return `New notification from ${subject}`; + }, + - getText(notification) { + + async getText(notification) { + - return notification.content; + + const text = await getNotificationTextContent(notification); + + return text; + }, + - getHtml(notification) { + + async getHtml(notification) { + - return `

    ${notification.content}

    `; + + const html = await getNotificationHtmlContent(notification); + + return html; + }, + }); + }, + }); + }, + }); + ``` + +### Patch Changes + +- d55b8e3: Avoid sending broadcast emails as a fallback in case the entity-typed notification user can not be resolved. +- cdb630d: Add support for stream transport for debugging purposes +- 83faf24: Notification email processor supports allowing or denying specific email addresses from receiving notifications +- Updated dependencies + - @backstage/backend-plugin-api@0.8.0 + - @backstage/backend-common@0.24.0 + - @backstage/plugin-notifications-node@0.2.4 + - @backstage/catalog-model@1.6.0 + - @backstage/catalog-client@1.6.6 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.2.0-next.3 + +### Patch Changes + +- 83faf24: Notification email processor supports allowing or denying specific email addresses from receiving notifications +- Updated dependencies + - @backstage/backend-plugin-api@0.8.0-next.3 + - @backstage/backend-common@0.23.4-next.3 + - @backstage/catalog-model@1.6.0-next.0 + - @backstage/catalog-client@1.6.6-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.3 + +## 0.2.0-next.2 + +### Patch Changes + +- cdb630d: Add support for stream transport for debugging purposes +- Updated dependencies + - @backstage/backend-plugin-api@0.8.0-next.2 + - @backstage/plugin-notifications-node@0.2.4-next.2 + - @backstage/backend-common@0.23.4-next.2 + - @backstage/integration-aws-node@0.1.12 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.2.0-next.1 + +### Minor Changes + +- def53a7: **BREAKING** Following `NotificationTemplateRenderer` methods now return a Promise and **must** be awaited: `getSubject`, `getText` and `getHtml`. + + Required changes and example usage: + + ```diff + import { notificationsEmailTemplateExtensionPoint } from '@backstage/plugin-notifications-backend-module-email'; + import { Notification } from '@backstage/plugin-notifications-common'; + +import { getNotificationSubject, getNotificationTextContent, getNotificationHtmlContent } from 'my-notification-processing-library` + export const notificationsModuleEmailDecorator = createBackendModule({ + pluginId: 'notifications', + moduleId: 'email.templates', + register(reg) { + reg.registerInit({ + deps: { + emailTemplates: notificationsEmailTemplateExtensionPoint, + }, + async init({ emailTemplates }) { + emailTemplates.setTemplateRenderer({ + - getSubject(notification) { + + async getSubject(notification) { + - return `New notification from ${notification.source}`; + + const subject = await getNotificationSubject(notification); + + return `New notification from ${subject}`; + }, + - getText(notification) { + + async getText(notification) { + - return notification.content; + + const text = await getNotificationTextContent(notification); + + return text; + }, + - getHtml(notification) { + + async getHtml(notification) { + - return `

    ${notification.content}

    `; + + const html = await getNotificationHtmlContent(notification); + + return html; + }, + }); + }, + }); + }, + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration-aws-node@0.1.12 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.1 + +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.0 + +## 0.1.3 + +### Patch Changes + +- 4e4ef2b: Move notification processor filter parsing to common package +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-notifications-node@0.2.3-next.1 + +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-notifications-node@0.2.2-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.4 + +## 0.1.0 + +### Minor Changes + +- 07a789b: add notification filters + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-notifications-node@0.2.0 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## 0.1.0-next.3 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19-next.3 + - @backstage/plugin-notifications-common@0.0.4-next.0 + - @backstage/plugin-notifications-node@0.2.0-next.3 + - @backstage/backend-common@0.23.0-next.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## 0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19-next.2 + - @backstage/backend-common@0.23.0-next.2 + - @backstage/plugin-notifications-node@0.2.0-next.2 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.3 + +## 0.1.0-next.1 + +### Minor Changes + +- 07a789b: add notification filters + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19-next.1 + - @backstage/plugin-notifications-node@0.2.0-next.1 + - @backstage/backend-common@0.23.0-next.1 + +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.22.1-next.0 + - @backstage/backend-plugin-api@0.6.19-next.0 + - @backstage/plugin-notifications-node@0.1.5-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.3 + +## 0.0.1 + +### Patch Changes + +- d541ff6: Fixed email processor `esm` issue and config reading +- e538b10: Support relative links in notifications sent via email +- dbf2696: Allow sending notifications by email with the new notifications module +- Updated dependencies + - @backstage/catalog-model@1.5.0 + - @backstage/backend-common@0.22.0 + - @backstage/plugin-notifications-node@0.1.4 + - @backstage/backend-plugin-api@0.6.18 + - @backstage/catalog-client@1.6.5 + +## 0.0.1-next.1 + +### Patch Changes + +- d541ff6: Fixed email processor `esm` issue and config reading +- e538b10: Support relative links in notifications sent via email +- Updated dependencies + - @backstage/backend-common@0.22.0-next.2 + +## 0.0.1-next.0 + +### Patch Changes + +- dbf2696: Allow sending notifications by email with the new notifications module +- Updated dependencies + - @backstage/plugin-notifications-node@0.1.4-next.1 + - @backstage/backend-common@0.22.0-next.1 + - @backstage/backend-plugin-api@0.6.18-next.1 + +## @backstage/create-app@0.7.6-next.1 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/dev-utils@1.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + +## @backstage/plugin-mui-to-bui@0.2.1-next.1 + +### Patch Changes + +- 5c614ff: Updated BUI checkbox preview example to align with new component API. +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + +## example-app@0.2.115-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + - @backstage/plugin-mui-to-bui@0.2.1-next.1 + +## example-app-next@0.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + +## techdocs-cli-embedded-app@0.2.114-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 diff --git a/docs/releases/v1.45.0-next.2-changelog.md b/docs/releases/v1.45.0-next.2-changelog.md new file mode 100644 index 0000000000..4bac9094e7 --- /dev/null +++ b/docs/releases/v1.45.0-next.2-changelog.md @@ -0,0 +1,1448 @@ +# Release v1.45.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.45.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.45.0-next.2) + +## @backstage/backend-app-api@1.3.0-next.1 + +### Minor Changes + +- a17d9df: Updates API for `instanceMetadata` service to return a list of plugins not features. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/backend-plugin-api@1.5.0-next.1 + +### Minor Changes + +- a17d9df: Promote `instanceMetadata` service to main entrypoint. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/ui@0.9.0-next.2 + +### Minor Changes + +- 539cf26: **BREAKING**: Migrated Avatar component from Base UI to custom implementation with size changes: + + - Base UI-specific props are no longer supported + - Size values have been updated: + - New `x-small` size added (1.25rem / 20px) + - `small` size unchanged (1.5rem / 24px) + - `medium` size unchanged (2rem / 32px, default) + - `large` size **changed from 3rem to 2.5rem** (40px) + - New `x-large` size added (3rem / 48px) + + Migration: + + ```diff + # Remove Base UI-specific props + - + + + + # Update large size usage to x-large for same visual size + - + + + ``` + + Added `purpose` prop for accessibility control (`'informative'` or `'decoration'`). + +- 134151f: Fixing styles on SearchField in Backstage UI after migration to CSS modules. `SearchField` has now its own set of class names. We previously used class names from `TextField` but this approach was creating some confusion so going forward in your theme you'll be able to theme `TextField` and `SearchField` separately. + +### Patch Changes + +- d01de00: Fix broken external links in Backstage UI Header component. +- deaa427: Fixed Text component to prevent `truncate` prop from being spread to the underlying DOM element. +- 1059f95: Improved the Link component structure in Backstage UI. +- 6874094: Migrated CellProfile component from Base UI Avatar to Backstage UI Avatar component. +- 719d772: Avatar components in x-small and small sizes now display only one initial instead of two, improving readability at smaller dimensions. +- 3b18d80: Fixed RadioGroup radio button ellipse distortion by preventing flex shrink and grow. +- e16ece5: Set the color-scheme property depending on theme + +## @backstage/plugin-catalog@1.32.0-next.1 + +### Minor Changes + +- a521911: Add support for customizable icons in `SearchResultListItemBlueprint` and related components + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-catalog-backend@3.2.0-next.1 + +### Minor Changes + +- 2d229b2: Enable YAML merge keys in yamlPlaceholderResolver +- 9d3ec06: Make YAML merge (<<:) support configurable in the Backstage Catalog instead of always being enabled +- 8c26af4: Enable YAML merge keys in yamlPlaceholderResolver + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.12.0-next.1 + +### Minor Changes + +- 980f240: Moved from `ldapjs` dependency to `ldapts` + + ### Breaking Changes + + **Type Migration** + + Custom transformers must now accept `Entry` from ldapts instead of `SearchEntry` + from ldapjs The Entry type provides direct property access without need for + `.object()` or `.raw()` methods. + + If you have custom user or group transformers, update the signature from: + + ```typescript + (vendor: LdapVendor, config: UserConfig, entry: SearchEntry) => + Promise; + ``` + + to + + ```typescript + (vendor: LdapVendor, config: UserConfig, entry: Entry) => + Promise; + ``` + + **Search Options** + + Updated LDAP search configuration `typesOnly: false` → `attributeValues: true` + This inverts the boolean logic: ldapjs used negative form while ldapts uses + positive form. Both achieve the same result: retrieving attribute values rather + than just attribute names. + + Update LDAP search options in configuration from + + ```yaml + options: + typesOnly: false + ``` + + to + + ```yaml + options: + attributeValues: true + ``` + + **API Changes** Removed `LdapClient.searchStreaming()` method. Users should + migrate to `LdapClient.search()` instead + + If you're using `searchStreaming` directly: + + ```typescript + // Before + await client.searchStreaming(dn, options, async entry => { + // process each entry + }); + + // After + const entries = await client.search(dn, options); + for (const entry of entries) { + // process each entry + } + ``` + + > **_NOTE:_**: Both methods have always loaded all entries into memory. The + > searchStreaming method was only needed internally to handle ldapjs's + > event-based API. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-node@1.20.0-next.1 + +### Minor Changes + +- 9d3ec06: Make YAML merge (<<:) support configurable in the Backstage Catalog instead of always being enabled +- 8c26af4: Enable YAML merge keys in yamlPlaceholderResolver + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-gateway-backend@1.1.0-next.1 + +### Minor Changes + +- a17d9df: Update usage of the `instanceMetadata` service. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.10.0-next.1 + +### Minor Changes + +- ff96d7e: fix scaffolder action createDeployToken to allow usage of oauth tokens + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-search@1.5.0-next.1 + +### Minor Changes + +- a521911: Add support for customizable icons in `SearchResultListItemBlueprint` and related components + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-search-react@1.10.0-next.1 + +### Minor Changes + +- a521911: Add support for customizable icons in `SearchResultListItemBlueprint` and related components + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + +## @backstage/plugin-techdocs@1.16.0-next.1 + +### Minor Changes + +- a521911: Add support for customizable icons in `SearchResultListItemBlueprint` and related components + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/backend-defaults@0.13.1-next.1 + +### Patch Changes + +- 91ab2eb: Fix a bug in the Gitlab URL reader where `search` did not handle multiple globs +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-app-api@1.3.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/backend-dynamic-feature-service@0.7.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-app-node@0.1.39-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/backend-openapi-utils@0.6.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/backend-test-utils@1.10.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-app-api@1.3.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/cli@0.34.5-next.1 + +### Patch Changes + +- da19cb5: Fix inconsistent behavior in the `new` command for the `@internal` scope: it now consistently defaults to the `backstage-plugin-` infix whether the `--scope` option is not set or it's set to `internal`. +- b2bef92: Convert all enums to erasable-syntax compliant patterns + +## @backstage/core-app-api@1.19.2-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.1 + +## @backstage/core-components@0.18.3-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.1 + +## @backstage/core-plugin-api@1.11.2-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns + +## @backstage/create-app@0.7.6-next.2 + +### Patch Changes + +- 9f939a6: Added `@backstage/plugin-app-visualizer` to the app in the `--next` template. + +## @backstage/frontend-plugin-api@0.12.2-next.1 + +### Patch Changes + +- 878c251: Updated to `ExtensionInput` to make all type parameters optional. +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + +## @backstage/repo-tools@0.15.4-next.1 + +### Patch Changes + +- 8f56eae: Updated knip-reports to detect dependencies in dev/alpha pattern +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-api-docs@0.13.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-app-backend@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-app-node@0.1.39-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-app-node@0.1.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-app-visualizer@0.1.25-next.1 + +### Patch Changes + +- e81b3f0: Improve tree visualizer to use a horizontal layout and fill the content space. +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + +## @backstage/plugin-auth-backend@0.25.6-next.1 + +### Patch Changes + +- 51ff7d8: Allow configuring dynamic client registration token expiration with config `auth.experimentalDynamicClientRegistration.tokenExpiration`. + + Maximum expiration for the DCR token is 24 hours. Default expiration is 1 hour. + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-backend@0.25.6-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-backend@0.25.6-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-node@0.6.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-azure@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.11.2-next.1 + +### Patch Changes + +- 999d1c1: Added configurable `pageSizes` for GitHub GraphQL API queries to prevent `RESOURCE_LIMITS_EXCEEDED` errors with organizations with large number of repositories. Please see the [GitHub Discovery documentation](https://backstage.io/docs/integrations/github/discovery#configuration) for new configuration options. +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.16-next.1 + +### Patch Changes + +- 999d1c1: Added configurable `pageSizes` for GitHub GraphQL API queries to prevent `RESOURCE_LIMITS_EXCEEDED` errors with organizations with large number of teams and members. Please see the [GitHub Org Data documentation](https://backstage.io/docs/integrations/github/org#configuration-details) for new configuration options. +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-catalog-backend-module-github@0.11.2-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.7.5-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.6-next.1 + +### Patch Changes + +- 70745c5: Correctly handle entity removal computation when DB count query returns string +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-logs@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.1 + +### Patch Changes + +- a5bcb2a: fix wrong dereferencing for AsyncApi 3 documents +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-catalog-graph@0.5.3-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-catalog-react@1.21.3-next.1 + +### Patch Changes + +- 2b7924b: Apply default ordering of templates +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-devtools-backend@0.5.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-devtools-common@0.1.19-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-devtools-common@0.1.19-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.1 + +## @backstage/plugin-events-backend@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-azure@0.2.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-gerrit@0.2.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-github@0.4.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-gitlab@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-kafka@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-node@0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-kubernetes-backend@0.20.4-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-kubernetes-node@0.3.6-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-kubernetes-node@0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-mcp-actions-backend@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-notifications-backend@0.5.12-next.1 + +### Patch Changes + +- 15fb764: Show default settings for notifications even before receiving first notification. + + Previously, it was not possible for the users to see or modify their notification settings until they had received at + least one notification from specific origin or topic. + This update ensures that default settings are displayed from the outset, + allowing users to customize their preferences immediately. + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-notifications-node@0.2.21-next.1 + - @backstage/plugin-signals-node@0.1.26-next.1 + +## @backstage/plugin-notifications-backend-module-email@0.3.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-notifications-node@0.2.21-next.1 + +## @backstage/plugin-notifications-backend-module-slack@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-notifications-node@0.2.21-next.1 + +## @backstage/plugin-notifications-node@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-signals-node@0.1.26-next.1 + +## @backstage/plugin-permission-backend@0.7.6-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-permission-common@0.9.3-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns + +## @backstage/plugin-permission-node@0.10.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-proxy-backend@0.6.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-proxy-node@0.1.10-next.1 + +## @backstage/plugin-proxy-node@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-scaffolder-backend@3.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.10.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.16-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.15-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-notifications-node@0.2.21-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.15-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.3.5-next.1 + +## @backstage/plugin-scaffolder-node@0.12.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-test-utils@1.10.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-search-backend@2.0.8-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-catalog@0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-explore@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-pg@0.5.50-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-techdocs@0.4.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + - @backstage/plugin-techdocs-node@1.13.9-next.1 + +## @backstage/plugin-search-backend-node@1.3.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + +## @backstage/plugin-signals@0.0.25-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- f0f006e: Fixes a bug where the `SignalClient` would try to subscribe to the same channel twice after an error, instead of just once. +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-signals-backend@0.3.10-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-signals-node@0.1.26-next.1 + +## @backstage/plugin-signals-node@0.1.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + +## @backstage/plugin-techdocs-backend@2.1.2-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-techdocs-node@1.13.9-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + +### Patch Changes + +- 6929480: ExpandableCollapse Techdocs Addon was breaking native sidebar collapse on Firefox +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + +## @backstage/plugin-techdocs-node@1.13.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-user-settings-backend@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-signals-node@0.1.26-next.1 + +## example-app@0.2.115-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-signals@0.0.25-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-search@1.5.0-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + - @backstage/plugin-catalog-graph@0.5.3-next.1 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/plugin-api-docs@0.13.1-next.1 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + +## example-app-next@0.0.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-signals@0.0.25-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-search@1.5.0-next.1 + - @backstage/plugin-app-visualizer@0.1.25-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + - @backstage/plugin-catalog-graph@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/plugin-api-docs@0.13.1-next.1 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + +## example-backend@0.0.44-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.1 + - @backstage/plugin-kubernetes-backend@0.20.4-next.1 + - @backstage/plugin-techdocs-backend@2.1.2-next.1 + - @backstage/plugin-signals-backend@0.3.10-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/plugin-notifications-backend@0.5.12-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-backend@0.7.6-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-search-backend@2.0.8-next.1 + - @backstage/plugin-auth-backend@0.25.6-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.1 + - @backstage/plugin-mcp-actions-backend@0.1.5-next.1 + - @backstage/plugin-scaffolder-backend@3.0.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.10-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.8-next.1 + - @backstage/plugin-app-backend@0.5.8-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.1 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-devtools-backend@0.5.11-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-proxy-backend@0.6.8-next.1 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.1 + - @backstage/plugin-search-backend-module-explore@0.3.9-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## techdocs-cli-embedded-app@0.2.114-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + +## @internal/plugin-todo-list-backend@1.0.45-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 diff --git a/docs/releases/v1.45.0-next.3-changelog.md b/docs/releases/v1.45.0-next.3-changelog.md new file mode 100644 index 0000000000..0f66b0ca65 --- /dev/null +++ b/docs/releases/v1.45.0-next.3-changelog.md @@ -0,0 +1,282 @@ +# Release v1.45.0-next.3 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.45.0-next.3](https://backstage.github.io/upgrade-helper/?to=1.45.0-next.3) + +## @backstage/backend-plugin-api@1.5.0-next.2 + +### Minor Changes + +- 62fc2de: Explicitly mark `coreServices.rootInstanceMetadata` as a root service. + +## @backstage/repo-tools@0.16.0-next.2 + +### Minor Changes + +- 11c61f2: The `package-docs` command will now automatically use a `typedoc.json` file if one exists at the root of your project. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.2 + +## @backstage/ui@0.9.0-next.3 + +### Minor Changes + +- 83c100e: **BREAKING**: Removed `Collapsible` component. Migrate to `Accordion` or use React Aria `Disclosure`. + + ## Migration Path 1: Accordion (Opinionated Styled Component) + + Accordion provides preset styling with a similar component structure. + + ```diff + - import { Collapsible } from '@backstage/ui'; + + import { Accordion, AccordionTrigger, AccordionPanel } from '@backstage/ui'; + + - + - } /> + - Content + - + + + + + + + Content + + + ``` + + CSS classes: `.bui-CollapsibleRoot` → `.bui-Accordion`, `.bui-CollapsibleTrigger` → `.bui-AccordionTrigger` (now on heading element), `.bui-CollapsiblePanel` → `.bui-AccordionPanel` + + ## Migration Path 2: React Aria Disclosure (Full Customization) + + For custom styling without preset styles: + + ```tsx + import { Disclosure, Button, DisclosurePanel } from 'react-aria-components'; + + + + Content + ; + ``` + +- 816af0f: **BREAKING**: The `SelectProps` interface now accepts a generic type parameter for selection mode. + + Added searchable and multiple selection support to Select component. The component now accepts `searchable`, `selectionMode`, and `searchPlaceholder` props to enable filtering and multi-selection modes. + + Migration: If you're using `SelectProps` type directly, update from `SelectProps` to `SelectProps<'single' | 'multiple'>`. Component usage remains backward compatible. + +### Patch Changes + +- 35a3614: Fixed CSS issues in Select component including popover width constraints, focus outline behavior, and overflow handling. +- 01476f0: Improved visual consistency of PasswordField, SearchField, and MenuAutocomplete components. +- 836b0c7: Fixed dialog backdrop appearance in dark mode. +- 6d35a6b: Removed `@base-ui-components/react` dependency as all components now use React Aria Components. +- 7839e7b: Added `loading` prop to Button and ButtonIcon components for displaying spinner during async operations. +- a00fb88: Fixed Table Row component to properly support opening links in new tabs via right-click or Cmd+Click when using the href prop. + +## @backstage/plugin-notifications-backend@0.6.0-next.2 + +### Minor Changes + +- 87e597c: Adds support for default configuration for an entire notification channel. + This setting will also be inherited down to origins and topics while still respecting the users individual choices. + + This will be handy if you want to use a "opt-in" strategy. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.2.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.2 + - @backstage/plugin-notifications-node@0.2.21-next.2 + +## @backstage/plugin-notifications-common@0.2.0-next.1 + +### Minor Changes + +- 87e597c: Adds support for default configuration for an entire notification channel. + This setting will also be inherited down to origins and topics while still respecting the users individual choices. + + This will be handy if you want to use a "opt-in" strategy. + +## @backstage/backend-test-utils@1.10.0-next.2 + +### Patch Changes + +- f3001fd: Tweak some of the mock services to have more precise types +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.2 + +## @backstage/core-components@0.18.3-next.2 + +### Patch Changes + +- 96ad674: Line numbers in LogViewer will not be selectable in UI anymore + +## @backstage/create-app@0.7.6-next.3 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/frontend-plugin-api@0.12.2-next.2 + +### Patch Changes + +- 7c6a66d: Added support for plugin-relative `attachTo` declarations for extension definitions. This allows for the creation of extension and extension blueprints that attach to other extensions of a particular `kind` in the same plugin, rather than needing to provide the exact extension ID. This is particularly useful when wanting to provide extension blueprints with a built-in hierarchy where the extensions created from one blueprint attach to extensions created from the other blueprint, for example: + + ```ts + // kind: 'tabbed-page' + const parentPage = TabbedPageBlueprint.make({ + params: {....} + }) + // attachTo: { kind: 'tabbed-page', input: 'tabs' } + const child1 = TabContentBlueprint.make({ + name: 'tab1', + params: {....} + }) + ``` + +- Updated dependencies + - @backstage/core-components@0.18.3-next.2 + +## @backstage/plugin-app-visualizer@0.1.25-next.2 + +### Patch Changes + +- 722e2df: Migrated to use `@backstage/ui`. +- Updated dependencies + - @backstage/ui@0.9.0-next.3 + - @backstage/frontend-plugin-api@0.12.2-next.2 + - @backstage/core-components@0.18.3-next.2 + +## @backstage/plugin-catalog-graph@0.5.3-next.2 + +### Patch Changes + +- a2d7ae7: Ensure the catalog graph entity card respects the height prop so the visualization scales down properly on wide screens. +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.2 + - @backstage/frontend-plugin-api@0.12.2-next.2 + - @backstage/core-components@0.18.3-next.2 + +## @backstage/plugin-catalog-react@1.21.3-next.2 + +### Patch Changes + +- 36d7582: Added missing i18n +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.2-next.2 + - @backstage/core-components@0.18.3-next.2 + +## @backstage/plugin-home@0.8.14-next.1 + +### Patch Changes + +- 2ac5d29: Allow customization of VisitList by adding optional enrichVisit, transformPathname, canSave functions to VisitsStorageApi, along with VisitDisplayProvider for colors, labels +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.2 + - @backstage/frontend-plugin-api@0.12.2-next.2 + - @backstage/core-components@0.18.3-next.2 + +## @backstage/plugin-kubernetes-backend@0.20.4-next.2 + +### Patch Changes + +- 1906d37: Updated dependency `@kubernetes/client-node` to `1.4.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.2 + - @backstage/plugin-kubernetes-common@0.9.8-next.1 + - @backstage/plugin-kubernetes-node@0.3.6-next.2 + +## @backstage/plugin-kubernetes-common@0.9.8-next.1 + +### Patch Changes + +- 1906d37: Updated dependency `@kubernetes/client-node` to `1.4.0`. + +## @backstage/plugin-kubernetes-node@0.3.6-next.2 + +### Patch Changes + +- 1906d37: Updated dependency `@kubernetes/client-node` to `1.4.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.2 + - @backstage/plugin-kubernetes-common@0.9.8-next.1 + +## @backstage/plugin-kubernetes-react@0.5.13-next.1 + +### Patch Changes + +- 1906d37: Updated dependency `@kubernetes/client-node` to `1.4.0`. +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.8-next.1 + - @backstage/core-components@0.18.3-next.2 + +## @backstage/plugin-notifications@0.5.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.2.0-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.2 + - @backstage/core-components@0.18.3-next.2 + +## @backstage/plugin-notifications-backend-module-email@0.3.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.2.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.2 + - @backstage/plugin-notifications-node@0.2.21-next.2 + +## @backstage/plugin-notifications-backend-module-slack@0.2.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.2.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.2 + - @backstage/plugin-notifications-node@0.2.21-next.2 + +## @backstage/plugin-notifications-node@0.2.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.2.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.2 + +## @backstage/plugin-org@0.6.46-next.1 + +### Patch Changes + +- 6db9e7e: Improved responsiveness of GroupProfileCard component +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.2 + - @backstage/frontend-plugin-api@0.12.2-next.2 + - @backstage/core-components@0.18.3-next.2 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.2.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.2 + - @backstage/plugin-notifications-node@0.2.21-next.2 + +## example-backend@0.0.44-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-backend@0.6.0-next.2 + - @backstage/backend-plugin-api@1.5.0-next.2 + - @backstage/plugin-kubernetes-backend@0.20.4-next.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.2 + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-scaffolder-backend@3.0.1-next.1 + - @backstage/plugin-search-backend@2.0.8-next.1 diff --git a/microsite/data/plugins/stackoverflow-teams.yaml b/microsite/data/plugins/stackoverflow-teams.yaml index c2fc1f5480..262a6e9c69 100644 --- a/microsite/data/plugins/stackoverflow-teams.yaml +++ b/microsite/data/plugins/stackoverflow-teams.yaml @@ -6,5 +6,5 @@ category: Discovery description: Provide seamless access to Stack Overflow Teams most relevant data, allowing you to display the top users, top tags, and top questions directly within Backstage. It also allows to securely create SO Teams questions from Backstage. documentation: https://stackoverflowteams.help/en/articles/9692515-backstage-io-integration iconUrl: /img/stack-overflow-logo.svg -npmPackageName: 'backstage-plugin-stack-overflow-teams' +npmPackageName: '@stackoverflow/backstage-plugin-stack-overflow-teams' addedDate: '2025-06-10' diff --git a/microsite/data/plugins/targetboard.yaml b/microsite/data/plugins/targetboard.yaml new file mode 100644 index 0000000000..2cac367eec --- /dev/null +++ b/microsite/data/plugins/targetboard.yaml @@ -0,0 +1,10 @@ +--- +title: TargetBoard +author: TargetBoard +authorUrl: https://www.targetboard.ai +category: Metrics +description: Embed TargetBoard dashboards and metric cards inside Backstage to visualize real-time engineering performance, KPIs, and delivery metrics. +documentation: https://github.com/targetboard/backstage-plugin/blob/main/README.md +iconUrl: https://app.targetboard.ai/assets/TargetBoard-Backstage-logo.svg +npmPackageName: '@targetboard/backstage-plugin' +addedDate: '2025-11-02' diff --git a/microsite/data/plugins/usage-statistics.yaml b/microsite/data/plugins/usage-statistics.yaml new file mode 100644 index 0000000000..d32fb54ac4 --- /dev/null +++ b/microsite/data/plugins/usage-statistics.yaml @@ -0,0 +1,9 @@ +--- +title: Usage Statistics +author: CodeVerse-GP +authorUrl: https://github.com/CodeVerse-GP +category: Monitoring +description: Shows usage statistics for scaffolder templates +documentation: https://github.com/CodeVerse-GP/usage-statistics/blob/main/README.md +npmPackageName: '@codeverse-gp/plugin-usage-statistics' +addedDate: '2025-11-05' diff --git a/microsite/sidebars.ts b/microsite/sidebars.ts index a5c735d2f4..9a4f03620f 100644 --- a/microsite/sidebars.ts +++ b/microsite/sidebars.ts @@ -62,6 +62,42 @@ export default { 'overview/support', 'getting-started/keeping-backstage-updated', ], + ...(process.env.GOLDEN_PATH + ? { + 'Golden Paths': [ + { + type: 'category', + label: '001 - create-app', + items: [ + 'golden-path/create-app/index', + 'golden-path/create-app/npx-create-app', + 'golden-path/create-app/local-development', + 'golden-path/create-app/installing-plugins', + 'golden-path/create-app/logging-in', + 'golden-path/create-app/custom-theme', + 'golden-path/create-app/keeping-backstage-updated', + ], + }, + { + type: 'category', + label: '002 - Plugins', + items: [ + 'golden-path/plugins/index', + 'golden-path/plugins/why-build-plugins', + 'golden-path/plugins/sustainable-plugin-development', + { + type: 'category', + label: 'Backend Plugins', + items: [ + 'golden-path/plugins/backend/001-first-steps', + 'golden-path/plugins/backend/002-poking-around', + ], + }, + ], + }, + ], + } + : {}), 'Core Features': [ { type: 'category', diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 9040e75d86..20c3f39fbd 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -2460,14 +2460,14 @@ __metadata: linkType: hard "@mdx-js/react@npm:^3.0.0": - version: 3.1.0 - resolution: "@mdx-js/react@npm:3.1.0" + version: 3.1.1 + resolution: "@mdx-js/react@npm:3.1.1" dependencies: "@types/mdx": "npm:^2.0.0" peerDependencies: "@types/react": ">=16" react: ">=16" - checksum: 10/cf89d6392c76091622fb647f205e1ab5cbdf5edd4401dde7092138cefc9fbb6d61428aa63557de0bccca3695d5a8854dd4a93b34a27cb8e27369da7eaeaa3e73 + checksum: 10/52a740e2f37761694fa94d4704b7825084b4055616a95c8b8f4c1676190d399ddc5cdbb399ffc45b550beecd30497a7224c2e5b05bf43ecb668c7473641037d1 languageName: node linkType: hard diff --git a/package.json b/package.json index 614ec28f35..5039c29e2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.45.0-next.0", + "version": "1.45.0-next.3", "backstage": { "cli": { "new": { @@ -45,6 +45,7 @@ "lint:docs": "node ./scripts/check-docs-quality", "lint:peer-deps": "backstage-repo-tools peer-deps", "lint:type-deps": "backstage-repo-tools type-deps", + "mui-to-bui": "node scripts/mui-to-bui/backstage-migration-analytics.js", "new": "backstage-cli new", "prepare": "husky", "prettier:check": "prettier --check .", @@ -106,6 +107,7 @@ "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@yarnpkg/plugin-npm@npm:^3.1.0": "patch:@yarnpkg/plugin-npm@npm%3A3.1.0#~/.yarn/patches/@yarnpkg-plugin-npm-npm-3.1.0-6533d0f5a1.patch", + "GendocuPublicApis": "npm:gendocu-public-apis@^1.0.0", "ast-types@0.14.2": "patch:ast-types@npm%3A0.14.2#./.yarn/patches/ast-types-npm-0.14.2-43c4ac4b0d.patch", "ast-types@^0.14.1": "patch:ast-types@npm%3A0.14.2#./.yarn/patches/ast-types-npm-0.14.2-43c4ac4b0d.patch", "ast-types@npm:0.14.2": "patch:ast-types@npm%3A0.16.1#./.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch", @@ -115,7 +117,6 @@ "csstype@npm:^3.1.2": "3.0.9", "csstype@npm:^3.1.3": "3.0.9", "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch", - "GendocuPublicApis": "npm:gendocu-public-apis@^1.0.0", "recast@npm:0.23.9>ast-types": "patch:ast-types@npm%3A0.16.1#./.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch" }, "dependencies": { @@ -166,6 +167,7 @@ "sloc": "^0.3.1", "sort-package-json": "^2.8.0", "storybook": "^9.1.7", + "ts-morph": "^24.0.0", "typedoc": "^0.28.0", "typescript": "~5.7.0", "vite": "^7.1.5" diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index ffa195a96c..c632471817 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,40 @@ # example-app-next +## 0.0.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-signals@0.0.25-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-search@1.5.0-next.1 + - @backstage/plugin-app-visualizer@0.1.25-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + - @backstage/plugin-catalog-graph@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/plugin-api-docs@0.13.1-next.1 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + +## 0.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + ## 0.0.29-next.0 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 746b415db7..5dae3c9750 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.29-next.0", + "version": "0.0.29-next.2", "backstage": { "role": "frontend" }, diff --git a/packages/app-next/public/index.html b/packages/app-next/public/index.html index 63ab0bec0c..74387edea3 100644 --- a/packages/app-next/public/index.html +++ b/packages/app-next/public/index.html @@ -4,6 +4,7 @@ + + { + it('should only load modules if the plugin is present', async () => { + let loadedModule = false; + const backend1 = new BackendInitializer(baseFactories); + const testModule = createBackendModule({ + pluginId: 'test', + moduleId: 'producer', + register(reg) { + reg.registerInit({ + deps: {}, + async init() { + loadedModule = true; + }, + }); + }, + }); + await backend1.add(testModule); + await backend1.start(); + expect(loadedModule).toBe(false); + + const backend2 = new BackendInitializer(baseFactories); + await backend2.add(testModule); + await backend2.add( + createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: {}, + async init() {}, + }); + }, + }), + ); + await backend2.start(); + expect(loadedModule).toBe(true); + }); + it('should initialize root scoped services', async () => { const ref1 = createServiceRef<{ x: number }>({ id: '1', @@ -1074,7 +1110,7 @@ describe('BackendInitializer', () => { }); it('should properly add plugins + modules to the instance metadata service', async () => { - expect.assertions(2); + expect.assertions(1); const backend = new BackendInitializer(baseFactories); const plugin = createBackendPlugin({ pluginId: 'test', @@ -1090,31 +1126,25 @@ describe('BackendInitializer', () => { register(reg) { reg.registerInit({ deps: { - instanceMetadata: instanceMetadataServiceRef, + instanceMetadata: coreServices.rootInstanceMetadata, }, async init({ instanceMetadata }) { - expect(instanceMetadata.getInstalledFeatures()).toEqual([ + await expect( + instanceMetadata.getInstalledPlugins(), + ).resolves.toEqual([ { pluginId: 'test', - type: 'plugin', - }, - { - pluginId: 'test', - moduleId: 'test', - type: 'module', + modules: [ + { + moduleId: 'test', + }, + ], }, { pluginId: 'instance-metadata', - type: 'plugin', + modules: [], }, ]); - expect(instanceMetadata.getInstalledFeatures().map(String)).toEqual( - [ - 'plugin{pluginId=test}', - 'module{moduleId=test,pluginId=test}', - 'plugin{pluginId=instance-metadata}', - ], - ); }, }); }, @@ -1135,6 +1165,67 @@ describe('BackendInitializer', () => { await backend.start(); }); + it('should ignore modules that do not have a matching plugin', async () => { + expect.assertions(1); + const backend = new BackendInitializer(baseFactories); + const instanceMetadataPlugin = createBackendPlugin({ + pluginId: 'instance-metadata', + register(reg) { + reg.registerInit({ + deps: { + instanceMetadata: coreServices.rootInstanceMetadata, + }, + async init({ instanceMetadata }) { + await expect( + instanceMetadata.getInstalledPlugins(), + ).resolves.toEqual([ + { + pluginId: 'instance-metadata', + modules: [], + }, + ]); + }, + }); + }, + }); + const module = createBackendModule({ + pluginId: 'test', + moduleId: 'test', + register(reg) { + reg.registerInit({ + deps: {}, + async init() {}, + }); + }, + }); + backend.add(module); + backend.add(instanceMetadataPlugin); + await backend.start(); + }); + + it('should prevent writes to the instance metadata service', async () => { + expect.assertions(1); + const backend = new BackendInitializer(baseFactories); + const plugin = createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: { + instanceMetadata: coreServices.rootInstanceMetadata, + }, + async init({ instanceMetadata }) { + const plugins = await instanceMetadata.getInstalledPlugins(); + await expect(() => { + (plugins[0] as any).pluginId = 'foo'; + }).toThrow(/Cannot assign to read only property/); + }, + }); + }, + }); + backend.add(plugin); + await backend.start(); + }); + it('should properly wait for all modules that consume an extension point to really finish, before starting the module that provides that extension point', async () => { expect.assertions(3); const backend = new BackendInitializer(baseFactories); diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index 09b22e3a7a..e7480d3beb 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -36,14 +36,11 @@ import type { // eslint-disable-next-line @backstage/no-relative-monorepo-imports import type { InternalServiceFactory } from '../../../backend-plugin-api/src/services/system/types'; import { ForwardedError, ConflictError, assertError } from '@backstage/errors'; -import { - instanceMetadataServiceRef, - BackendFeatureMeta, -} from '@backstage/backend-plugin-api/alpha'; import { DependencyGraph } from '../lib/DependencyGraph'; import { ServiceRegistry } from './ServiceRegistry'; import { createInitializationLogger } from './createInitializationLogger'; -import { unwrapFeature } from './helpers'; +import { deepFreeze, unwrapFeature } from './helpers'; +import type { RootInstanceMetadataServicePluginInfo } from '@backstage/backend-plugin-api'; export interface BackendRegisterInit { consumes: Set; @@ -101,56 +98,52 @@ const instanceRegistry = new (class InstanceRegistry { }; })(); -function createInstanceMetadataServiceFactory( - registrations: InternalBackendRegistrations[], +function createRootInstanceMetadataServiceFactory( + rawRegistrations: InternalBackendRegistrations[], ) { - const installedFeatures = registrations - .map(registration => { - if (registration.featureType === 'registrations') { - return registration - .getRegistrations() - .map(feature => { - if (feature.type === 'plugin') { - return Object.defineProperty( - { - type: 'plugin', - pluginId: feature.pluginId, - }, - 'toString', - { - enumerable: false, - configurable: true, - value: () => `plugin{pluginId=${feature.pluginId}}`, - }, - ); - } else if (feature.type === 'module') { - return Object.defineProperty( - { - type: 'module', - pluginId: feature.pluginId, - moduleId: feature.moduleId, - }, - 'toString', - { - enumerable: false, - configurable: true, - value: () => - `module{moduleId=${feature.moduleId},pluginId=${feature.pluginId}}`, - }, - ); - } - // Ignore unknown feature types. - return undefined; - }) - .filter(Boolean) as BackendFeatureMeta[]; - } - return []; - }) - .flat(); + const installedPlugins: Map = + new Map(); + const registrations = rawRegistrations + .filter(registration => registration.featureType === 'registrations') + .flatMap(registration => registration.getRegistrations()); + const plugins = registrations.filter( + registration => registration.type === 'plugin', + ); + const modules = registrations.filter( + registration => registration.type === 'module', + ); + for (const plugin of plugins) { + const { pluginId } = plugin; + if (!installedPlugins.get(pluginId)) { + installedPlugins.set(pluginId, { + pluginId, + modules: [], + }); + } + } + for (const module of modules) { + const { pluginId, moduleId } = module; + const installedPlugin = installedPlugins.get(pluginId); + if (installedPlugin) { + (installedPlugin.modules as Array<{ moduleId: string }>).push({ + moduleId, + }); + } + } + return createServiceFactory({ - service: instanceMetadataServiceRef, + service: coreServices.rootInstanceMetadata, deps: {}, - factory: async () => ({ getInstalledFeatures: () => installedFeatures }), + factory: async () => { + const readonlyInstalledPlugins = deepFreeze([ + ...installedPlugins.values(), + ]); + const instanceMetadata = { + getInstalledPlugins: () => Promise.resolve(readonlyInstalledPlugins), + }; + + return instanceMetadata; + }, }); } @@ -255,7 +248,7 @@ export class BackendInitializer { await this.#applyBackendFeatureLoaders(this.#registeredFeatureLoaders); this.#serviceRegistry.add( - createInstanceMetadataServiceFactory(this.#registrations), + createRootInstanceMetadataServiceFactory(this.#registrations), ); // This makes sure that any uncaught errors or unhandled rejections are diff --git a/packages/backend-app-api/src/wiring/helpers.ts b/packages/backend-app-api/src/wiring/helpers.ts index ffb7e3b079..1be7f62da2 100644 --- a/packages/backend-app-api/src/wiring/helpers.ts +++ b/packages/backend-app-api/src/wiring/helpers.ts @@ -34,3 +34,22 @@ export function unwrapFeature( return feature; } + +/** @internal */ +export type DeepReadonly = { + readonly [K in keyof T]: T[K] extends object ? DeepReadonly : T[K]; +}; + +/** + * Deeply freezes an object by recursively freezing all of its properties. + * From https://gist.github.com/tkrotoff/e997cd6ff8d6cf6e51e6bb6146407fc3 + + * https://stackoverflow.com/a/69656011 + */ +export function deepFreeze(obj: T) { + // Can cause: "Type instantiation is excessively deep and possibly infinite." + // @ts-expect-error + Object.values(obj).forEach( + value => Object.isFrozen(value) || deepFreeze(value), + ); + return Object.freeze(obj) as DeepReadonly; +} diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 62c478f6f7..f168e43ee4 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-defaults +## 0.13.1-next.1 + +### Patch Changes + +- 91ab2eb: Fix a bug in the Gitlab URL reader where `search` did not handle multiple globs +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-app-api@1.3.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + ## 0.13.1-next.0 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 4884c9d30d..a089998dee 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.13.1-next.0", + "version": "0.13.1-next.1", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-defaults/report-alpha.api.md b/packages/backend-defaults/report-alpha.api.md index 58277b5e1e..2ca3525946 100644 --- a/packages/backend-defaults/report-alpha.api.md +++ b/packages/backend-defaults/report-alpha.api.md @@ -5,6 +5,7 @@ ```ts import { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha'; import { ActionsService } from '@backstage/backend-plugin-api/alpha'; +import { InstanceMetadataService } from '@backstage/backend-plugin-api/alpha'; import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public (undocumented) @@ -21,5 +22,12 @@ export const actionsServiceFactory: ServiceFactory< 'singleton' >; +// @alpha @deprecated (undocumented) +export const instanceMetadataServiceFactory: ServiceFactory< + InstanceMetadataService, + 'plugin', + 'singleton' +>; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index 4b201fded3..44df59b5f1 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -38,6 +38,7 @@ import { eventsServiceFactory } from '@backstage/plugin-events-node'; import { actionsRegistryServiceFactory, actionsServiceFactory, + instanceMetadataServiceFactory, } from '@backstage/backend-defaults/alpha'; export const defaultServiceFactories = [ @@ -65,6 +66,7 @@ export const defaultServiceFactories = [ // alpha services actionsRegistryServiceFactory, actionsServiceFactory, + instanceMetadataServiceFactory, ]; /** diff --git a/packages/ui/src/components/Collapsible/index.ts b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/index.ts similarity index 87% rename from packages/ui/src/components/Collapsible/index.ts rename to packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/index.ts index 6a7f8e8816..00ee75400a 100644 --- a/packages/ui/src/components/Collapsible/index.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { Collapsible } from './Collapsible'; +export { instanceMetadataServiceFactory } from './instanceMetadataServiceFactory'; diff --git a/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.test.ts b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.test.ts new file mode 100644 index 0000000000..2368ea74e8 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.test.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2025 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 { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { instanceMetadataServiceFactory } from './instanceMetadataServiceFactory'; +import { startTestBackend } from '@backstage/backend-test-utils'; +import { instanceMetadataServiceRef } from '@backstage/backend-plugin-api/alpha'; +import Router from 'express-promise-router'; +import request from 'supertest'; + +describe('instanceMetadataServiceFactory', () => { + it('should create an instance metadata service', async () => { + const pluginSubject = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + instanceMetadata: instanceMetadataServiceRef, + httpRouter: coreServices.httpRouter, + }, + async init({ instanceMetadata, httpRouter }) { + const router = Router(); + router.get('/instance-metadata', async (_, res) => { + const metadata = await instanceMetadata.getInstalledFeatures(); + res.json(metadata); + }); + httpRouter.use(router); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginSubject, instanceMetadataServiceFactory], + }); + + const response = await request(server) + .get('/api/my-plugin/instance-metadata') + .expect(200); + expect(response.body).toEqual([{ pluginId: 'my-plugin', type: 'plugin' }]); + }); +}); diff --git a/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.ts b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.ts new file mode 100644 index 0000000000..bd2d427a59 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2025 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 { + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { + BackendFeatureMeta, + InstanceMetadataService, + instanceMetadataServiceRef, +} from '@backstage/backend-plugin-api/alpha'; + +/** + * @alpha + * @deprecated use {@link @backstage/backend-plugin-api#coreServices.rootInstanceMetadata} instead + */ +export const instanceMetadataServiceFactory = createServiceFactory({ + service: instanceMetadataServiceRef, + deps: { + instanceMetadata: coreServices.rootInstanceMetadata, + }, + factory: async ({ instanceMetadata }) => { + const plugins = await instanceMetadata.getInstalledPlugins(); + const features: BackendFeatureMeta[] = []; + for (const plugin of plugins) { + features.push({ + type: 'plugin' as const, + pluginId: plugin.pluginId, + }); + for (const module of plugin.modules) { + features.push({ + type: 'module' as const, + pluginId: plugin.pluginId, + moduleId: module.moduleId, + }); + } + } + const service: InstanceMetadataService = { + getInstalledFeatures: () => features, + }; + + return service; + }, +}); diff --git a/packages/backend-defaults/src/alpha/index.ts b/packages/backend-defaults/src/alpha/index.ts index 13bb439acd..744d5bc552 100644 --- a/packages/backend-defaults/src/alpha/index.ts +++ b/packages/backend-defaults/src/alpha/index.ts @@ -15,3 +15,4 @@ */ export { actionsRegistryServiceFactory } from './entrypoints/actionsRegistry'; export { actionsServiceFactory } from './entrypoints/actions'; +export { instanceMetadataServiceFactory } from './entrypoints/instanceMetadata'; diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts index 65cd275574..c5ce323c54 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts @@ -670,6 +670,17 @@ describe('GitlabUrlReader', () => { ); }); + it('works when there are multiple globs', async () => { + const result = await gitlabProcessor.search( + 'https://gitlab.com/backstage/mock/tree/main/**/docs/**/index.*', + ); + expect(result.etag).toBe('sha123abc'); + expect(result.files.length).toBe(1); + expect(result.files[0].url).toBe( + 'https://gitlab.com/backstage/mock/tree/main/docs/index.md', + ); + }); + it('works for the naive case', async () => { const result = await gitlabProcessor.search( 'https://gitlab.com/backstage/mock/tree/main/**/index.*', diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts index 19f1846dda..ee290e31e6 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts @@ -319,14 +319,10 @@ export class GitlabUrlReader implements UrlReaderService { */ private getStaticPart(globPattern: string) { const segments = globPattern.split('/'); - let i = segments.length; - while ( - i > 0 && - new Minimatch(segments.slice(0, i).join('/')).match(globPattern) - ) { - i--; - } - return segments.slice(0, i).join('/'); + const globIndex = segments.findIndex(segment => segment.match(/[*?]/)); + return globIndex === -1 + ? globPattern + : segments.slice(0, globIndex).join('/'); } toString() { diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 30bce3a09d..6e5ff62fd1 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/backend-dynamic-feature-service +## 0.7.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-app-node@0.1.39-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + ## 0.7.6-next.0 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index d203e6d72a..c96ad18d94 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-dynamic-feature-service", - "version": "0.7.6-next.0", + "version": "0.7.6-next.1", "description": "Backstage dynamic feature service", "backstage": { "role": "node-library" diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index f1917123a4..109df60032 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/backend-openapi-utils +## 0.6.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + ## 0.6.3-next.0 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index a70f729714..d88bfb2a91 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-openapi-utils", - "version": "0.6.3-next.0", + "version": "0.6.3-next.1", "description": "OpenAPI typescript support.", "backstage": { "role": "node-library" diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index fedc20cd49..a12734cc98 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/backend-plugin-api +## 1.5.0-next.2 + +### Minor Changes + +- 62fc2de: Explicitly mark `coreServices.rootInstanceMetadata` as a root service. + +## 1.5.0-next.1 + +### Minor Changes + +- a17d9df: Promote `instanceMetadata` service to main entrypoint. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + ## 1.4.5-next.0 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 78ff5d7131..90d3959658 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "1.4.5-next.0", + "version": "1.5.0-next.2", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" diff --git a/packages/backend-plugin-api/report.api.md b/packages/backend-plugin-api/report.api.md index 52843dec96..c46ed254c8 100644 --- a/packages/backend-plugin-api/report.api.md +++ b/packages/backend-plugin-api/report.api.md @@ -232,6 +232,11 @@ export namespace coreServices { const rootLogger: ServiceRef; const scheduler: ServiceRef; const urlReader: ServiceRef; + const rootInstanceMetadata: ServiceRef< + RootInstanceMetadataService, + 'root', + 'singleton' + >; } // @public @@ -578,6 +583,24 @@ export interface RootHttpRouterService { use(path: string, handler: Handler): void; } +// @public (undocumented) +export interface RootInstanceMetadataService { + // (undocumented) + getInstalledPlugins: () => Promise< + ReadonlyArray + >; +} + +// @public (undocumented) +export interface RootInstanceMetadataServicePluginInfo { + // (undocumented) + readonly modules: ReadonlyArray<{ + moduleId: string; + }>; + // (undocumented) + readonly pluginId: string; +} + // @public export interface RootLifecycleService extends LifecycleService { // (undocumented) diff --git a/packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts b/packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts index 869d361343..a82a261d9d 100644 --- a/packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts +++ b/packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 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. diff --git a/packages/backend-plugin-api/src/services/definitions/RootInstanceMetadataService.ts b/packages/backend-plugin-api/src/services/definitions/RootInstanceMetadataService.ts new file mode 100644 index 0000000000..c324fed331 --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/RootInstanceMetadataService.ts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +/** @public */ +export interface RootInstanceMetadataServicePluginInfo { + readonly pluginId: string; + readonly modules: ReadonlyArray<{ + moduleId: string; + }>; +} + +/** @public */ +export interface RootInstanceMetadataService { + getInstalledPlugins: () => Promise< + ReadonlyArray + >; +} diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index 8c8c6c0f82..887b05ee4e 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -277,4 +277,16 @@ export namespace coreServices { export const urlReader = createServiceRef< import('./UrlReaderService').UrlReaderService >({ id: 'core.urlReader' }); + + /** + * Information about the current Backstage instance. + * + * @public + */ + export const rootInstanceMetadata = createServiceRef< + import('./RootInstanceMetadataService').RootInstanceMetadataService + >({ + id: 'core.rootInstanceMetadata', + scope: 'root', + }); } diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index c811a513a8..6bcee4b043 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -85,4 +85,8 @@ export type { UrlReaderServiceSearchResponseFile, } from './UrlReaderService'; export type { BackstageUserInfo, UserInfoService } from './UserInfoService'; +export type { + RootInstanceMetadataService, + RootInstanceMetadataServicePluginInfo, +} from './RootInstanceMetadataService'; export { coreServices } from './coreServices'; diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 7625dc43c4..a30fc1fa68 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/backend-test-utils +## 1.10.0-next.2 + +### Patch Changes + +- f3001fd: Tweak some of the mock services to have more precise types +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.2 + +## 1.10.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-app-api@1.3.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + ## 1.10.0-next.0 ### Minor Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 7ce66eaa85..ea0c2d0c85 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "1.10.0-next.0", + "version": "1.10.0-next.2", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" diff --git a/packages/backend-test-utils/report.api.md b/packages/backend-test-utils/report.api.md index e7763329a8..da5002275b 100644 --- a/packages/backend-test-utils/report.api.md +++ b/packages/backend-test-utils/report.api.md @@ -35,6 +35,7 @@ import { PermissionsService } from '@backstage/backend-plugin-api'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { RootHealthService } from '@backstage/backend-plugin-api'; import { RootHttpRouterService } from '@backstage/backend-plugin-api'; +import { RootInstanceMetadataService } from '@backstage/backend-plugin-api'; import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; @@ -229,11 +230,7 @@ export namespace mockServices { export function events(): EventsService; // (undocumented) export namespace events { - const factory: () => ServiceFactory< - EventsService, - 'plugin', - 'singleton' | 'multiton' - >; + const factory: () => ServiceFactory; const mock: ( partialImpl?: Partial | undefined, ) => ServiceMock; @@ -319,7 +316,7 @@ export namespace mockServices { const // (undocumented) factory: ( options?: Options | undefined, - ) => ServiceFactory; + ) => ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -344,6 +341,21 @@ export namespace mockServices { ) => ServiceMock; } // (undocumented) + export function rootInstanceMetadata(): RootInstanceMetadataService; + // (undocumented) + export namespace rootInstanceMetadata { + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; + const // (undocumented) + factory: () => ServiceFactory< + RootInstanceMetadataService, + 'root', + 'singleton' + >; + } + // (undocumented) export namespace rootLifecycle { const // (undocumented) factory: () => ServiceFactory; @@ -353,7 +365,7 @@ export namespace mockServices { ) => ServiceMock; } // (undocumented) - export function rootLogger(options?: rootLogger.Options): LoggerService; + export function rootLogger(options?: rootLogger.Options): RootLoggerService; // (undocumented) export namespace rootLogger { // (undocumented) @@ -363,7 +375,7 @@ export namespace mockServices { const // (undocumented) factory: ( options?: Options | undefined, - ) => ServiceFactory; + ) => ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, diff --git a/packages/backend-test-utils/src/services/mockServices.ts b/packages/backend-test-utils/src/services/mockServices.ts index f7d57d3fb1..9e941db3bb 100644 --- a/packages/backend-test-utils/src/services/mockServices.ts +++ b/packages/backend-test-utils/src/services/mockServices.ts @@ -34,7 +34,7 @@ import { DatabaseService, DiscoveryService, HttpAuthService, - LoggerService, + RootInstanceMetadataService, PermissionsService, RootConfigService, SchedulerService, @@ -43,6 +43,7 @@ import { UserInfoService, coreServices, createServiceFactory, + RootLoggerService, } from '@backstage/backend-plugin-api'; import { ConfigReader } from '@backstage/config'; import { EventsService, eventsServiceRef } from '@backstage/plugin-events-node'; @@ -76,14 +77,15 @@ function createLoggerMock() { function simpleFactoryWithOptions< TService, TScope extends 'root' | 'plugin', + TInstances extends 'singleton' | 'multiton', TOptions extends [options?: object] = [], >( - ref: ServiceRef, + ref: ServiceRef, factory: (...options: TOptions) => TService, -): (...options: TOptions) => ServiceFactory { +): (...options: TOptions) => ServiceFactory { const factoryWithOptions = (...options: TOptions) => createServiceFactory({ - service: ref as ServiceRef, + service: ref as ServiceRef, deps: {}, async factory() { return factory(...options); @@ -92,8 +94,8 @@ function simpleFactoryWithOptions< return Object.assign( factoryWithOptions, factoryWithOptions(...([undefined] as unknown as TOptions)), - ) as ServiceFactory & - ((...options: TOptions) => ServiceFactory); + ) as ServiceFactory & + ((...options: TOptions) => ServiceFactory); } /** @@ -177,7 +179,7 @@ export namespace mockServices { })); } - export function rootLogger(options?: rootLogger.Options): LoggerService { + export function rootLogger(options?: rootLogger.Options): RootLoggerService { return MockRootLoggerService.create(options); } export namespace rootLogger { @@ -556,4 +558,19 @@ export namespace mockServices { subscribe: jest.fn(), })); } + + export function rootInstanceMetadata(): RootInstanceMetadataService { + return { + getInstalledPlugins: () => Promise.resolve([]), + }; + } + export namespace rootInstanceMetadata { + export const mock = simpleMock(coreServices.rootInstanceMetadata, () => ({ + getInstalledPlugins: jest.fn(), + })); + export const factory = simpleFactoryWithOptions( + coreServices.rootInstanceMetadata, + rootInstanceMetadata, + ); + } } diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 12e2ac4f1d..cb84bcbc4c 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,60 @@ # example-backend +## 0.0.44-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-backend@0.6.0-next.2 + - @backstage/backend-plugin-api@1.5.0-next.2 + - @backstage/plugin-kubernetes-backend@0.20.4-next.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.2 + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-scaffolder-backend@3.0.1-next.1 + - @backstage/plugin-search-backend@2.0.8-next.1 + +## 0.0.44-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.1 + - @backstage/plugin-kubernetes-backend@0.20.4-next.1 + - @backstage/plugin-techdocs-backend@2.1.2-next.1 + - @backstage/plugin-signals-backend@0.3.10-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/plugin-notifications-backend@0.5.12-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-backend@0.7.6-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-search-backend@2.0.8-next.1 + - @backstage/plugin-auth-backend@0.25.6-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.1 + - @backstage/plugin-mcp-actions-backend@0.1.5-next.1 + - @backstage/plugin-scaffolder-backend@3.0.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.10-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.8-next.1 + - @backstage/plugin-app-backend@0.5.8-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.1 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-devtools-backend@0.5.11-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-proxy-backend@0.6.8-next.1 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.1 + - @backstage/plugin-search-backend-module-explore@0.3.9-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + ## 0.0.44-next.0 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index d6efe662c7..199304ae5a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.44-next.0", + "version": "0.0.44-next.2", "backstage": { "role": "backend" }, diff --git a/packages/backend/src/instanceMetadata.ts b/packages/backend/src/instanceMetadata.ts index 5f835f3117..026fc6fd02 100644 --- a/packages/backend/src/instanceMetadata.ts +++ b/packages/backend/src/instanceMetadata.ts @@ -17,21 +17,21 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { instanceMetadataServiceRef } from '@backstage/backend-plugin-api/alpha'; -// Example usage of the instance metadata service to log the installed features. +// Example usage of the instance metadata service to log the installed plugins. export default createBackendPlugin({ pluginId: 'instance-metadata-logging', register(env) { env.registerInit({ deps: { - instanceMetadata: instanceMetadataServiceRef, + instanceMetadata: coreServices.rootInstanceMetadata, logger: coreServices.logger, }, async init({ instanceMetadata, logger }) { + const plugins = await instanceMetadata.getInstalledPlugins(); logger.info( - `Installed features on this instance: ${instanceMetadata - .getInstalledFeatures() + `Installed plugins on this instance: ${plugins + .map(e => e.pluginId) .join(', ')}`, ); }, diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 5c18ed6c8a..8f0c1a8a21 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/cli +## 0.34.5-next.1 + +### Patch Changes + +- da19cb5: Fix inconsistent behavior in the `new` command for the `@internal` scope: it now consistently defaults to the `backstage-plugin-` infix whether the `--scope` option is not set or it's set to `internal`. +- b2bef92: Convert all enums to erasable-syntax compliant patterns + ## 0.34.5-next.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index a3ed006a3d..bdd8a120c3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.34.5-next.0", + "version": "0.34.5-next.1", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" diff --git a/packages/cli/src/modules/build/lib/builder/types.ts b/packages/cli/src/modules/build/lib/builder/types.ts index 937bd157c9..f80d0d1306 100644 --- a/packages/cli/src/modules/build/lib/builder/types.ts +++ b/packages/cli/src/modules/build/lib/builder/types.ts @@ -13,13 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { BackstagePackage, BackstagePackageJson } from '@backstage/cli-node'; -export enum Output { - esm, - cjs, - types, +export const Output = { + esm: 0, + cjs: 1, + types: 2, +} as const; + +/** + * @public + */ +export type Output = (typeof Output)[keyof typeof Output]; + +/** + * @public + */ +export namespace Output { + export type esm = typeof Output.esm; + export type cjs = typeof Output.cjs; + export type types = typeof Output.types; } export type BuildOptions = { diff --git a/packages/cli/src/modules/new/lib/preparation/loadPortableTemplateConfig.test.ts b/packages/cli/src/modules/new/lib/preparation/loadPortableTemplateConfig.test.ts index b8a7940bcf..f8167ef339 100644 --- a/packages/cli/src/modules/new/lib/preparation/loadPortableTemplateConfig.test.ts +++ b/packages/cli/src/modules/new/lib/preparation/loadPortableTemplateConfig.test.ts @@ -196,7 +196,7 @@ describe('loadPortableTemplateConfig', () => { private: true, version: '0.1.0', packageNamePrefix: '@internal/', - packageNamePluginInfix: 'plugin-', + packageNamePluginInfix: 'backstage-plugin-', }); }); @@ -316,7 +316,7 @@ describe('loadPortableTemplateConfig', () => { version: '0.1.0', private: true, packageNamePrefix: '@internal/', - packageNamePluginInfix: 'plugin-', + packageNamePluginInfix: 'backstage-plugin-', }); await expect( @@ -333,7 +333,7 @@ describe('loadPortableTemplateConfig', () => { version: '0.1.0', private: true, packageNamePrefix: '@internal/', - packageNamePluginInfix: 'plugin-', + packageNamePluginInfix: 'backstage-plugin-', }); }); }); diff --git a/packages/cli/src/modules/new/lib/preparation/loadPortableTemplateConfig.ts b/packages/cli/src/modules/new/lib/preparation/loadPortableTemplateConfig.ts index 5ef61bfb6b..2e736d9c29 100644 --- a/packages/cli/src/modules/new/lib/preparation/loadPortableTemplateConfig.ts +++ b/packages/cli/src/modules/new/lib/preparation/loadPortableTemplateConfig.ts @@ -70,6 +70,21 @@ type LoadConfigOptions = { overrides?: Partial; }; +function computePackageNamePluginInfix( + packageNamePrefix: string, + namePluginInfix?: string, +) { + const packageNamePluginInfix = + namePluginInfix ?? + (packageNamePrefix.includes('backstage') + ? defaults.packageNamePluginInfix + : 'backstage-plugin-'); + + return { + packageNamePluginInfix, + }; +} + export async function loadPortableTemplateConfig( options: LoadConfigOptions = {}, ): Promise { @@ -116,6 +131,16 @@ export async function loadPortableTemplateConfig( templateNameConflicts.set(pointer.name, rawPointer); } + const packageNamePrefix = + overrides.packageNamePrefix ?? + config?.globals?.namePrefix ?? + defaults.packageNamePrefix; + + const { packageNamePluginInfix } = computePackageNamePluginInfix( + packageNamePrefix, + overrides.packageNamePluginInfix ?? config?.globals?.namePluginInfix, + ); + return { isUsingDefaultTemplates: !config?.templates, templatePointers: templatePointerEntries.map(({ pointer }) => pointer), @@ -126,14 +151,8 @@ export async function loadPortableTemplateConfig( overrides.publishRegistry ?? config?.globals?.publishRegistry ?? defaults.publishRegistry, - packageNamePrefix: - overrides.packageNamePrefix ?? - config?.globals?.namePrefix ?? - defaults.packageNamePrefix, - packageNamePluginInfix: - overrides.packageNamePluginInfix ?? - config?.globals?.namePluginInfix ?? - defaults.packageNamePluginInfix, + packageNamePrefix, + packageNamePluginInfix, }; } diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index dbab1f871d..0fd09f851b 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/core-app-api +## 1.19.2-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.1 + ## 1.19.2-next.0 ### Patch Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 7cd3712cc0..3ce23e2422 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/core-app-api", - "version": "1.19.2-next.0", + "version": "1.19.2-next.1", "description": "Core app API used by Backstage apps", "backstage": { "role": "web-library" diff --git a/packages/core-app-api/src/apis/system/ApiFactoryRegistry.ts b/packages/core-app-api/src/apis/system/ApiFactoryRegistry.ts index 5f56793cae..1824937a02 100644 --- a/packages/core-app-api/src/apis/system/ApiFactoryRegistry.ts +++ b/packages/core-app-api/src/apis/system/ApiFactoryRegistry.ts @@ -31,11 +31,11 @@ export type ApiFactoryScope = | 'app' // Factories registered in the app, overriding default ones | 'static'; // APIs that can't be overridden, e.g. config -enum ScopePriority { - default = 10, - app = 50, - static = 100, -} +const ScopePriority = { + default: 10, + app: 50, + static: 100, +} as const; type FactoryTuple = { priority: number; diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 63a2846889..b4d7f1c7b0 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/core-components +## 0.18.3-next.2 + +### Patch Changes + +- 96ad674: Line numbers in LogViewer will not be selectable in UI anymore + +## 0.18.3-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.1 + ## 0.18.3-next.0 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index cbd3450886..958f566c88 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/core-components", - "version": "0.18.3-next.0", + "version": "0.18.3-next.2", "description": "Core components used by Backstage plugins and apps", "backstage": { "role": "web-library" diff --git a/packages/core-components/report.api.md b/packages/core-components/report.api.md index 9c9992deff..02fbb04805 100644 --- a/packages/core-components/report.api.md +++ b/packages/core-components/report.api.md @@ -283,11 +283,18 @@ export interface DependencyGraphProps // @public export namespace DependencyGraphTypes { - export enum Alignment { - DOWN_LEFT = 'DL', - DOWN_RIGHT = 'DR', - UP_LEFT = 'UL', - UP_RIGHT = 'UR', + // (undocumented) + export type Alignment = (typeof Alignment)[keyof typeof Alignment]; + // (undocumented) + export namespace Alignment { + // (undocumented) + export type DOWN_LEFT = typeof Alignment.DOWN_LEFT; + // (undocumented) + export type DOWN_RIGHT = typeof Alignment.DOWN_RIGHT; + // (undocumented) + export type UP_LEFT = typeof Alignment.UP_LEFT; + // (undocumented) + export type UP_RIGHT = typeof Alignment.UP_RIGHT; } export type DependencyEdge = T & { from: string; @@ -298,25 +305,54 @@ export namespace DependencyGraphTypes { export type DependencyNode = T & { id: string; }; - export enum Direction { - BOTTOM_TOP = 'BT', - LEFT_RIGHT = 'LR', - RIGHT_LEFT = 'RL', - TOP_BOTTOM = 'TB', - } - export enum LabelPosition { + // (undocumented) + export type Direction = (typeof Direction)[keyof typeof Direction]; + // (undocumented) + export namespace Direction { // (undocumented) - CENTER = 'c', + export type BOTTOM_TOP = typeof Direction.BOTTOM_TOP; // (undocumented) - LEFT = 'l', + export type LEFT_RIGHT = typeof Direction.LEFT_RIGHT; // (undocumented) - RIGHT = 'r', + export type RIGHT_LEFT = typeof Direction.RIGHT_LEFT; + // (undocumented) + export type TOP_BOTTOM = typeof Direction.TOP_BOTTOM; } - export enum Ranker { - LONGEST_PATH = 'longest-path', - NETWORK_SIMPLEX = 'network-simplex', - TIGHT_TREE = 'tight-tree', + // (undocumented) + export type LabelPosition = + (typeof LabelPosition)[keyof typeof LabelPosition]; + // (undocumented) + export namespace LabelPosition { + // (undocumented) + export type CENTER = typeof LabelPosition.CENTER; + // (undocumented) + export type LEFT = typeof LabelPosition.LEFT; + // (undocumented) + export type RIGHT = typeof LabelPosition.RIGHT; } + const Direction: { + readonly TOP_BOTTOM: 'TB'; + readonly BOTTOM_TOP: 'BT'; + readonly LEFT_RIGHT: 'LR'; + readonly RIGHT_LEFT: 'RL'; + }; + // (undocumented) + export type Ranker = (typeof Ranker)[keyof typeof Ranker]; + // (undocumented) + export namespace Ranker { + // (undocumented) + export type LONGEST_PATH = typeof Ranker.LONGEST_PATH; + // (undocumented) + export type NETWORK_SIMPLEX = typeof Ranker.NETWORK_SIMPLEX; + // (undocumented) + export type TIGHT_TREE = typeof Ranker.TIGHT_TREE; + } + const Alignment: { + readonly UP_LEFT: 'UL'; + readonly UP_RIGHT: 'UR'; + readonly DOWN_LEFT: 'DL'; + readonly DOWN_RIGHT: 'DR'; + }; export type RenderEdgeFunction = ( props: RenderEdgeProps, ) => ReactNode; @@ -344,12 +380,22 @@ export namespace DependencyGraphTypes { name?: string | undefined; }; }; + const Ranker: { + readonly NETWORK_SIMPLEX: 'network-simplex'; + readonly TIGHT_TREE: 'tight-tree'; + readonly LONGEST_PATH: 'longest-path'; + }; export type RenderLabelFunction = ( props: RenderLabelProps, ) => ReactNode; export type RenderLabelProps = { edge: DependencyEdge; }; + const LabelPosition: { + readonly LEFT: 'l'; + readonly RIGHT: 'r'; + readonly CENTER: 'c'; + }; export type RenderNodeFunction = ( props: RenderNodeProps, ) => ReactNode; diff --git a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx index 4b99402c3a..a4ef0ac682 100644 --- a/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx +++ b/packages/core-components/src/components/DependencyGraph/DependencyGraph.tsx @@ -79,7 +79,7 @@ export interface DependencyGraphProps */ nodes: Types.DependencyNode[]; /** - * Graph {@link DependencyGraphTypes.Direction | direction} + * Graph {@link DependencyGraphTypes.(Direction:namespace) | direction} * * @remarks * @@ -87,7 +87,7 @@ export interface DependencyGraphProps */ direction?: Types.Direction; /** - * Node {@link DependencyGraphTypes.Alignment | alignment} + * Node {@link DependencyGraphTypes.(Alignment:namespace) | alignment} */ align?: Types.Alignment; /** @@ -135,7 +135,7 @@ export interface DependencyGraphProps */ acyclicer?: 'greedy'; /** - * {@link DependencyGraphTypes.Ranker | Algorithm} used to rank nodes + * {@link DependencyGraphTypes.(Ranker:namespace) | Algorithm} used to rank nodes * * @remarks * @@ -143,7 +143,7 @@ export interface DependencyGraphProps */ ranker?: Types.Ranker; /** - * {@link DependencyGraphTypes.LabelPosition | Position} of label in relation to edge + * {@link DependencyGraphTypes.(LabelPosition:namespace) | Position} of label in relation to edge * * @remarks * diff --git a/packages/core-components/src/components/DependencyGraph/types.ts b/packages/core-components/src/components/DependencyGraph/types.ts index 4436f8d1aa..6a75df27b5 100644 --- a/packages/core-components/src/components/DependencyGraph/types.ts +++ b/packages/core-components/src/components/DependencyGraph/types.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ /** * Types used to customize and provide data to {@link DependencyGraph} @@ -134,23 +136,38 @@ export namespace DependencyGraphTypes { * * @public */ - export enum Direction { + export const Direction = { /** * Top to Bottom */ - TOP_BOTTOM = 'TB', + TOP_BOTTOM: 'TB', /** * Bottom to Top */ - BOTTOM_TOP = 'BT', + BOTTOM_TOP: 'BT', /** * Left to Right */ - LEFT_RIGHT = 'LR', + LEFT_RIGHT: 'LR', /** * Right to Left */ - RIGHT_LEFT = 'RL', + RIGHT_LEFT: 'RL', + } as const; + + /** + * @public + */ + export type Direction = (typeof Direction)[keyof typeof Direction]; + + /** + * @public + */ + export namespace Direction { + export type TOP_BOTTOM = typeof Direction.TOP_BOTTOM; + export type BOTTOM_TOP = typeof Direction.BOTTOM_TOP; + export type LEFT_RIGHT = typeof Direction.LEFT_RIGHT; + export type RIGHT_LEFT = typeof Direction.RIGHT_LEFT; } /** @@ -158,23 +175,38 @@ export namespace DependencyGraphTypes { * * @public */ - export enum Alignment { + export const Alignment = { /** * Up Left */ - UP_LEFT = 'UL', + UP_LEFT: 'UL', /** * Up Right */ - UP_RIGHT = 'UR', + UP_RIGHT: 'UR', /** * Down Left */ - DOWN_LEFT = 'DL', + DOWN_LEFT: 'DL', /** * Down Right */ - DOWN_RIGHT = 'DR', + DOWN_RIGHT: 'DR', + } as const; + + /** + * @public + */ + export type Alignment = (typeof Alignment)[keyof typeof Alignment]; + + /** + * @public + */ + export namespace Alignment { + export type UP_LEFT = typeof Alignment.UP_LEFT; + export type UP_RIGHT = typeof Alignment.UP_RIGHT; + export type DOWN_LEFT = typeof Alignment.DOWN_LEFT; + export type DOWN_RIGHT = typeof Alignment.DOWN_RIGHT; } /** @@ -182,15 +214,15 @@ export namespace DependencyGraphTypes { * * @public */ - export enum Ranker { + export const Ranker = { /** * {@link https://en.wikipedia.org/wiki/Network_simplex_algorithm | Network Simplex} algorithm */ - NETWORK_SIMPLEX = 'network-simplex', + NETWORK_SIMPLEX: 'network-simplex', /** * Tight Tree algorithm */ - TIGHT_TREE = 'tight-tree', + TIGHT_TREE: 'tight-tree', /** * Longest path algorithm * @@ -198,7 +230,21 @@ export namespace DependencyGraphTypes { * * Simplest and fastest */ - LONGEST_PATH = 'longest-path', + LONGEST_PATH: 'longest-path', + } as const; + + /** + * @public + */ + export type Ranker = (typeof Ranker)[keyof typeof Ranker]; + + /** + * @public + */ + export namespace Ranker { + export type NETWORK_SIMPLEX = typeof Ranker.NETWORK_SIMPLEX; + export type TIGHT_TREE = typeof Ranker.TIGHT_TREE; + export type LONGEST_PATH = typeof Ranker.LONGEST_PATH; } /** @@ -206,9 +252,24 @@ export namespace DependencyGraphTypes { * * @public */ - export enum LabelPosition { - LEFT = 'l', - RIGHT = 'r', - CENTER = 'c', + export const LabelPosition = { + LEFT: 'l', + RIGHT: 'r', + CENTER: 'c', + } as const; + + /** + * @public + */ + export type LabelPosition = + (typeof LabelPosition)[keyof typeof LabelPosition]; + + /** + * @public + */ + export namespace LabelPosition { + export type LEFT = typeof LabelPosition.LEFT; + export type RIGHT = typeof LabelPosition.RIGHT; + export type CENTER = typeof LabelPosition.CENTER; } } diff --git a/packages/core-components/src/components/LogViewer/styles.ts b/packages/core-components/src/components/LogViewer/styles.ts index 76e045ca32..238361f9a9 100644 --- a/packages/core-components/src/components/LogViewer/styles.ts +++ b/packages/core-components/src/components/LogViewer/styles.ts @@ -97,6 +97,7 @@ export const useStyles = makeStyles( marginRight: theme.spacing(1), cursor: 'pointer', flexShrink: 0, + userSelect: 'none', }, textHighlight: { background: alpha(theme.palette.info.main, 0.15), diff --git a/packages/core-components/src/layout/Sidebar/Bar.tsx b/packages/core-components/src/layout/Sidebar/Bar.tsx index 00fe6f96ae..bfa1e15d5e 100644 --- a/packages/core-components/src/layout/Sidebar/Bar.tsx +++ b/packages/core-components/src/layout/Sidebar/Bar.tsx @@ -97,11 +97,11 @@ const useStyles = makeStyles( { name: 'BackstageSidebar' }, ); -enum State { - Closed, - Idle, - Open, -} +const State = { + Closed: 0, + Idle: 1, + Open: 2, +} as const; /** @public */ export type SidebarProps = { @@ -144,7 +144,9 @@ const DesktopSidebar = (props: DesktopSidebarProps) => { theme => theme.breakpoints.down('md'), { noSsr: true }, ); - const [state, setState] = useState(State.Closed); + const [state, setState] = useState<(typeof State)[keyof typeof State]>( + State.Closed, + ); const hoverTimerRef = useRef(); const { isPinned, toggleSidebarPinState } = useSidebarPinState(); diff --git a/packages/core-components/src/layout/Sidebar/localStorage.ts b/packages/core-components/src/layout/Sidebar/localStorage.ts index 78ec355306..b62252e1df 100644 --- a/packages/core-components/src/layout/Sidebar/localStorage.ts +++ b/packages/core-components/src/layout/Sidebar/localStorage.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -enum LocalStorageKeys { - SIDEBAR_PIN_STATE = 'sidebarPinState', -} +const LocalStorageKeys = { + SIDEBAR_PIN_STATE: 'sidebarPinState', +} as const; export const LocalStorage = { getSidebarPinState(): boolean { diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index 98ffb44043..29dedfe6a7 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/core-plugin-api +## 1.11.2-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns + ## 1.11.2-next.0 ### Patch Changes diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index c80b6af1e8..430d081b49 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/core-plugin-api", - "version": "1.11.2-next.0", + "version": "1.11.2-next.1", "description": "Core API used by Backstage plugins", "backstage": { "role": "web-library" diff --git a/packages/core-plugin-api/report.api.md b/packages/core-plugin-api/report.api.md index b40088dc78..e1b1a243df 100644 --- a/packages/core-plugin-api/report.api.md +++ b/packages/core-plugin-api/report.api.md @@ -461,9 +461,21 @@ export type FeatureFlagsSaveOptions = { }; // @public -export enum FeatureFlagState { - Active = 1, - None = 0, +export const FeatureFlagState: { + readonly None: 0; + readonly Active: 1; +}; + +// @public (undocumented) +export type FeatureFlagState = + (typeof FeatureFlagState)[keyof typeof FeatureFlagState]; + +// @public (undocumented) +export namespace FeatureFlagState { + // (undocumented) + export type Active = typeof FeatureFlagState.Active; + // (undocumented) + export type None = typeof FeatureFlagState.None; } // @public @@ -696,9 +708,20 @@ export type SessionApi = { }; // @public -export enum SessionState { - SignedIn = 'SignedIn', - SignedOut = 'SignedOut', +export const SessionState: { + readonly SignedIn: 'SignedIn'; + readonly SignedOut: 'SignedOut'; +}; + +// @public (undocumented) +export type SessionState = (typeof SessionState)[keyof typeof SessionState]; + +// @public (undocumented) +export namespace SessionState { + // (undocumented) + export type SignedIn = typeof SessionState.SignedIn; + // (undocumented) + export type SignedOut = typeof SessionState.SignedOut; } // @public diff --git a/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts b/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts index 66260afa32..d4429975cc 100644 --- a/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { ApiRef, createApiRef } from '../system'; @@ -32,15 +34,29 @@ export type FeatureFlag = { * * @public */ -export enum FeatureFlagState { +export const FeatureFlagState = { /** * Feature flag inactive (disabled). */ - None = 0, + None: 0, /** * Feature flag active (enabled). */ - Active = 1, + Active: 1, +} as const; + +/** + * @public + */ +export type FeatureFlagState = + (typeof FeatureFlagState)[keyof typeof FeatureFlagState]; + +/** + * @public + */ +export namespace FeatureFlagState { + export type None = typeof FeatureFlagState.None; + export type Active = typeof FeatureFlagState.Active; } /** diff --git a/packages/core-plugin-api/src/apis/definitions/auth.ts b/packages/core-plugin-api/src/apis/definitions/auth.ts index f8686cb128..9a0ddcd958 100644 --- a/packages/core-plugin-api/src/apis/definitions/auth.ts +++ b/packages/core-plugin-api/src/apis/definitions/auth.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* We want to maintain the same information as an enum, so we disable the redeclaration warning */ +/* eslint-disable @typescript-eslint/no-redeclare */ import { ApiRef, createApiRef } from '../system'; import { IconComponent } from '../../icons/types'; @@ -269,15 +271,28 @@ export type ProfileInfo = { * * @public */ -export enum SessionState { +export const SessionState = { /** * User signed in. */ - SignedIn = 'SignedIn', + SignedIn: 'SignedIn', /** * User not signed in. */ - SignedOut = 'SignedOut', + SignedOut: 'SignedOut', +} as const; + +/** + * @public + */ +export type SessionState = (typeof SessionState)[keyof typeof SessionState]; + +/** + * @public + */ +export namespace SessionState { + export type SignedIn = typeof SessionState.SignedIn; + export type SignedOut = typeof SessionState.SignedOut; } /** diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 446a3a557e..f86586b990 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/create-app +## 0.7.6-next.3 + +### Patch Changes + +- Bumped create-app version. + +## 0.7.6-next.2 + +### Patch Changes + +- 9f939a6: Added `@backstage/plugin-app-visualizer` to the app in the `--next` template. + +## 0.7.6-next.1 + +### Patch Changes + +- Bumped create-app version. + ## 0.7.6-next.0 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 2f5ac3e944..d0b5850d58 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/create-app", - "version": "0.7.6-next.0", + "version": "0.7.6-next.3", "description": "A CLI that helps you create your own Backstage app", "backstage": { "role": "cli" diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index 6785fb9b52..51fa8dff84 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -53,6 +53,7 @@ import { version as repoTools } from '../../../repo-tools/package.json'; import { version as ui } from '../../../ui/package.json'; import { version as pluginApiDocs } from '../../../../plugins/api-docs/package.json'; +import { version as pluginAppVisualizer } from '../../../../plugins/app-visualizer/package.json'; import { version as pluginAppBackend } from '../../../../plugins/app-backend/package.json'; import { version as pluginAuthBackend } from '../../../../plugins/auth-backend/package.json'; import { version as pluginAuthBackendModuleGithubProvider } from '../../../../plugins/auth-backend-module-github-provider/package.json'; @@ -117,6 +118,7 @@ export const packageVersions = { '@backstage/repo-tools': repoTools, '@backstage/plugin-api-docs': pluginApiDocs, '@backstage/plugin-app-backend': pluginAppBackend, + '@backstage/plugin-app-visualizer': pluginAppVisualizer, '@backstage/plugin-auth-backend': pluginAuthBackend, '@backstage/plugin-auth-backend-module-github-provider': pluginAuthBackendModuleGithubProvider, diff --git a/packages/create-app/templates/next-app/packages/app/package.json.hbs b/packages/create-app/templates/next-app/packages/app/package.json.hbs index bc02fdc21a..726983fd69 100644 --- a/packages/create-app/templates/next-app/packages/app/package.json.hbs +++ b/packages/create-app/templates/next-app/packages/app/package.json.hbs @@ -21,6 +21,7 @@ "@backstage/frontend-defaults": "^{{ version '@backstage/frontend-defaults'}}", "@backstage/frontend-plugin-api": "^{{ version '@backstage/frontend-plugin-api'}}", "@backstage/integration-react": "^{{ version '@backstage/integration-react'}}", + "@backstage/plugin-app-visualizer": "^{{ version '@backstage/plugin-app-visualizer'}}", "@backstage/plugin-catalog": "^{{ version '@backstage/plugin-catalog'}}", "@backstage/plugin-notifications": "^{{ version '@backstage/plugin-notifications'}}", "@backstage/plugin-org": "^{{ version '@backstage/plugin-org'}}", diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index f9847fed5c..056bc4d9f9 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/dev-utils +## 1.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + ## 1.1.17-next.0 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index cb20f0cd8e..c7147efda9 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/dev-utils", - "version": "1.1.17-next.0", + "version": "1.1.17-next.1", "description": "Utilities for developing Backstage plugins.", "backstage": { "role": "web-library" diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index 13ec6e8a59..a07fdf352d 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -787,14 +787,8 @@ describe('instantiateAppNodeTree', () => { inputs: { [name in string]: | undefined - | ResolvedExtensionInput< - ExtensionInput - > - | Array< - ResolvedExtensionInput< - ExtensionInput - > - >; + | ResolvedExtensionInput + | Array>; }; }) { return [ diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts index 39fc88c19a..04082f8520 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.ts @@ -243,20 +243,10 @@ function resolveV1Inputs( } function resolveV2Inputs( - inputMap: { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + inputMap: { [inputName in string]: ExtensionInput }, attachments: ReadonlyMap, parentCollector: ErrorCollector<{ node: AppNode }>, -): ResolvedExtensionInputs<{ - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; -}> { +): ResolvedExtensionInputs<{ [inputName in string]: ExtensionInput }> { return mapValues(inputMap, (input, inputName) => { const attachedNodes = attachments.get(inputName) ?? []; const collector = parentCollector.child({ inputName }); @@ -297,12 +287,7 @@ function resolveV2Inputs( collector, ), ); - }) as ResolvedExtensionInputs<{ - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }>; + }) as ResolvedExtensionInputs<{ [inputName in string]: ExtensionInput }>; } /** @internal */ diff --git a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts index 2eacd0ae67..3ccdf5258f 100644 --- a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts +++ b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts @@ -44,6 +44,7 @@ function makeExt( version: 'v1', id, attachTo: { id: attachId, input: 'default' }, + inputs: {}, disabled: status === 'disabled', toString: expect.any(Function), } as Extension; @@ -61,6 +62,7 @@ function makeExtDef( name, attachTo: { id: attachId, input: 'default' }, disabled: status === 'disabled', + inputs: {}, override: () => ({} as ExtensionDefinition), } as ExtensionDefinition; } diff --git a/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts b/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts index 83d037902b..54953c169a 100644 --- a/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts +++ b/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts @@ -17,7 +17,7 @@ import { ApiHolder, AppNode, - ExtensionAttachToSpec, + ExtensionDefinitionAttachTo, ExtensionDataValue, ExtensionDataRef, ExtensionDefinition, @@ -36,7 +36,7 @@ export const OpaqueExtensionDefinition = OpaqueType.create<{ readonly kind?: string; readonly namespace?: string; readonly name?: string; - readonly attachTo: ExtensionAttachToSpec; + readonly attachTo: ExtensionDefinitionAttachTo; readonly disabled: boolean; readonly configSchema?: PortableSchema; readonly inputs: { @@ -67,25 +67,17 @@ export const OpaqueExtensionDefinition = OpaqueType.create<{ readonly kind?: string; readonly namespace?: string; readonly name?: string; - readonly attachTo: ExtensionAttachToSpec; + readonly attachTo: ExtensionDefinitionAttachTo; readonly disabled: boolean; readonly configSchema?: PortableSchema; - readonly inputs: { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; + readonly inputs: { [inputName in string]: ExtensionInput }; readonly output: Array; factory(context: { node: AppNode; apis: ApiHolder; config: object; inputs: ResolvedExtensionInputs<{ - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; + [inputName in string]: ExtensionInput; }>; }): Iterable>; }; diff --git a/packages/frontend-internal/src/wiring/InternalExtensionInput.ts b/packages/frontend-internal/src/wiring/InternalExtensionInput.ts new file mode 100644 index 0000000000..b816890f1a --- /dev/null +++ b/packages/frontend-internal/src/wiring/InternalExtensionInput.ts @@ -0,0 +1,36 @@ +/* + * 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 { ExtensionInput } from '@backstage/frontend-plugin-api'; +import { OpaqueType } from '@internal/opaque'; + +export type ExtensionInputContext = { + input: string; + kind?: string; + name?: string; +}; + +export const OpaqueExtensionInput = OpaqueType.create<{ + public: ExtensionInput; + versions: { + readonly version: undefined; + readonly context?: ExtensionInputContext; + withContext(context: ExtensionInputContext): ExtensionInput; + }; +}>({ + type: '@backstage/ExtensionInput', + versions: [undefined], +}); diff --git a/packages/frontend-internal/src/wiring/index.ts b/packages/frontend-internal/src/wiring/index.ts index b61294cb1f..1efcc7d16d 100644 --- a/packages/frontend-internal/src/wiring/index.ts +++ b/packages/frontend-internal/src/wiring/index.ts @@ -15,6 +15,10 @@ */ export { createExtensionDataContainer } from './createExtensionDataContainer'; -export { OpaqueSwappableComponentRef } from './InternalSwappableComponentRef'; export { OpaqueExtensionDefinition } from './InternalExtensionDefinition'; +export { + OpaqueExtensionInput, + type ExtensionInputContext, +} from './InternalExtensionInput'; export { OpaqueFrontendPlugin } from './InternalFrontendPlugin'; +export { OpaqueSwappableComponentRef } from './InternalSwappableComponentRef'; diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index 905b5cc9c2..9c97055ceb 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/frontend-plugin-api +## 0.12.2-next.2 + +### Patch Changes + +- 7c6a66d: Added support for plugin-relative `attachTo` declarations for extension definitions. This allows for the creation of extension and extension blueprints that attach to other extensions of a particular `kind` in the same plugin, rather than needing to provide the exact extension ID. This is particularly useful when wanting to provide extension blueprints with a built-in hierarchy where the extensions created from one blueprint attach to extensions created from the other blueprint, for example: + + ```ts + // kind: 'tabbed-page' + const parentPage = TabbedPageBlueprint.make({ + params: {....} + }) + // attachTo: { kind: 'tabbed-page', input: 'tabs' } + const child1 = TabContentBlueprint.make({ + name: 'tab1', + params: {....} + }) + ``` + +- Updated dependencies + - @backstage/core-components@0.18.3-next.2 + +## 0.12.2-next.1 + +### Patch Changes + +- 878c251: Updated to `ExtensionInput` to make all type parameters optional. +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + ## 0.12.2-next.0 ### Patch Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index 842e247e01..fec762ff63 100644 --- a/packages/frontend-plugin-api/package.json +++ b/packages/frontend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-plugin-api", - "version": "0.12.2-next.0", + "version": "0.12.2-next.2", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-plugin-api/report.api.md b/packages/frontend-plugin-api/report.api.md index 52a50659b6..c3dd12119f 100644 --- a/packages/frontend-plugin-api/report.api.md +++ b/packages/frontend-plugin-api/report.api.md @@ -259,7 +259,7 @@ export interface AppNodeInstance { // @public export interface AppNodeSpec { // (undocumented) - readonly attachTo: ExtensionAttachToSpec; + readonly attachTo: ExtensionAttachTo; // (undocumented) readonly config?: unknown; // (undocumented) @@ -399,13 +399,7 @@ export { createApiRef }; export function createExtension< UOutput extends ExtensionDataRef, TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType; @@ -413,6 +407,7 @@ export function createExtension< UFactoryOutput extends ExtensionDataValue, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined, + UParentInputs extends ExtensionDataRef = ExtensionDataRef, >( options: CreateExtensionOptions< TKind, @@ -420,7 +415,8 @@ export function createExtension< UOutput, TInputs, TConfigSchema, - UFactoryOutput + UFactoryOutput, + UParentInputs >, ): ExtensionDefinition<{ config: string extends keyof TConfigSchema @@ -453,19 +449,14 @@ export function createExtensionBlueprint< TParams extends object | ExtensionBlueprintDefineParams, UOutput extends ExtensionDataRef, TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, TKind extends string, + UParentInputs extends ExtensionDataRef, TDataRefs extends { [name in string]: ExtensionDataRef; } = never, @@ -477,7 +468,8 @@ export function createExtensionBlueprint< TInputs, TConfigSchema, UFactoryOutput, - TDataRefs + TDataRefs, + UParentInputs >, ): ExtensionBlueprint<{ kind: TKind; @@ -511,13 +503,7 @@ export type CreateExtensionBlueprintOptions< TParams extends object | ExtensionBlueprintDefineParams, UOutput extends ExtensionDataRef, TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; @@ -526,9 +512,11 @@ export type CreateExtensionBlueprintOptions< TDataRefs extends { [name in string]: ExtensionDataRef; }, + UParentInputs extends ExtensionDataRef, > = { kind: TKind; - attachTo: ExtensionAttachToSpec; + attachTo: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo; disabled?: boolean; inputs?: TInputs; output: Array; @@ -601,22 +589,18 @@ export type CreateExtensionOptions< TName extends string | undefined, UOutput extends ExtensionDataRef, TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, + UParentInputs extends ExtensionDataRef, > = { kind?: TKind; name?: TName; - attachTo: ExtensionAttachToSpec; + attachTo: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo; disabled?: boolean; inputs?: TInputs; output: Array; @@ -863,7 +847,7 @@ export interface Extension { } // @public (undocumented) -export type ExtensionAttachToSpec = +export type ExtensionAttachTo = | { id: string; input: string; @@ -873,6 +857,9 @@ export type ExtensionAttachToSpec = input: string; }>; +// @public @deprecated (undocumented) +export type ExtensionAttachToSpec = ExtensionAttachTo; + // @public (undocumented) export interface ExtensionBlueprint< T extends ExtensionBlueprintParameters = ExtensionBlueprintParameters, @@ -883,9 +870,11 @@ export interface ExtensionBlueprint< make< TName extends string | undefined, TParamsInput extends AnyParamsInput>, + UParentInputs extends ExtensionDataRef, >(args: { name?: TName; - attachTo?: ExtensionAttachToSpec; + attachTo?: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo, UParentInputs>; disabled?: boolean; params: TParamsInput extends ExtensionBlueprintDefineParams ? TParamsInput @@ -909,17 +898,18 @@ export interface ExtensionBlueprint< UFactoryOutput extends ExtensionDataValue, UNewOutput extends ExtensionDataRef, TExtraInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, + UParentInputs extends ExtensionDataRef, >(args: { name?: TName; - attachTo?: ExtensionAttachToSpec; + attachTo?: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo< + ExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, + UParentInputs + >; disabled?: boolean; inputs?: TExtraInputs & { [KName in keyof T['inputs']]?: `Error: Input '${KName & @@ -1008,13 +998,7 @@ export type ExtensionBlueprintParameters = { }; output?: ExtensionDataRef; inputs?: { - [KName in string]: ExtensionInput< - ExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [KName in string]: ExtensionInput; }; dataRefs?: { [name in string]: ExtensionDataRef; @@ -1109,6 +1093,11 @@ export type ExtensionDefinition< > = { $$type: '@backstage/ExtensionDefinition'; readonly T: T; + readonly inputs: { + [K in keyof T['inputs']]: ExtensionInput< + T['inputs'][K] extends ExtensionInput ? IData : never + >; + }; override< TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; @@ -1116,19 +1105,20 @@ export type ExtensionDefinition< UFactoryOutput extends ExtensionDataValue, UNewOutput extends ExtensionDataRef, TExtraInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TParamsInput extends AnyParamsInput_2>, + UParentInputs extends ExtensionDataRef, >( args: Expand< { - attachTo?: ExtensionAttachToSpec; + attachTo?: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo< + ExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, + UParentInputs + >; disabled?: boolean; inputs?: TExtraInputs & { [KName in keyof T['inputs']]?: `Error: Input '${KName & @@ -1210,6 +1200,41 @@ export type ExtensionDefinition< }>; }; +// @public +export type ExtensionDefinitionAttachTo< + UParentInputs extends ExtensionDataRef = ExtensionDataRef, +> = + | { + id: string; + input: string; + relative?: never; + } + | { + relative: { + kind?: string; + name?: string; + }; + input: string; + id?: never; + } + | ExtensionInput + | Array< + | { + id: string; + input: string; + relative?: never; + } + | { + relative: { + kind?: string; + name?: string; + }; + input: string; + id?: never; + } + | ExtensionInput + >; + // @public (undocumented) export type ExtensionDefinitionParameters = { kind?: string; @@ -1222,13 +1247,7 @@ export type ExtensionDefinitionParameters = { }; output?: ExtensionDataRef; inputs?: { - [KName in string]: ExtensionInput< - ExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [KName in string]: ExtensionInput; }; params?: object | ExtensionBlueprintDefineParams; }; @@ -1253,20 +1272,23 @@ export interface ExtensionInput< { optional?: true; } - >, + > = ExtensionDataRef, TConfig extends { singleton: boolean; optional: boolean; + } = { + singleton: boolean; + optional: boolean; }, > { // (undocumented) - $$type: '@backstage/ExtensionInput'; + readonly $$type: '@backstage/ExtensionInput'; // (undocumented) - config: TConfig; + readonly config: TConfig; // (undocumented) - extensionData: Array; + readonly extensionData: Array; // (undocumented) - replaces?: Array<{ + readonly replaces?: Array<{ id: string; input: string; }>; @@ -1625,18 +1647,17 @@ export const Progress: { export type ProgressProps = {}; // @public -export type ResolvedExtensionInput< - TExtensionInput extends ExtensionInput, -> = TExtensionInput['extensionData'] extends Array - ? { - node: AppNode; - } & ExtensionDataContainer - : never; +export type ResolvedExtensionInput = + TExtensionInput['extensionData'] extends Array + ? { + node: AppNode; + } & ExtensionDataContainer + : never; // @public export type ResolvedExtensionInputs< TInputs extends { - [name in string]: ExtensionInput; + [name in string]: ExtensionInput; }, > = { [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] diff --git a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts index f4fd2f3a6f..6c318d782a 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts @@ -15,12 +15,8 @@ */ import { createApiRef } from '@backstage/core-plugin-api'; -import { - FrontendPlugin, - Extension, - ExtensionDataRef, - ExtensionAttachToSpec, -} from '../../wiring'; +import { FrontendPlugin, Extension, ExtensionDataRef } from '../../wiring'; +import { ExtensionAttachTo } from '../../wiring/resolveExtensionDefinition'; /** * The specification for this {@link AppNode} in the {@link AppTree}. @@ -33,7 +29,7 @@ import { */ export interface AppNodeSpec { readonly id: string; - readonly attachTo: ExtensionAttachToSpec; + readonly attachTo: ExtensionAttachTo; readonly extension: Extension; readonly disabled: boolean; readonly config?: unknown; diff --git a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts index 471e933b12..988c5a15c0 100644 --- a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts @@ -203,10 +203,16 @@ describe('ApiBlueprint', () => { "optional": false, "singleton": false, }, + "context": { + "input": "test", + "kind": "api", + "name": "test", + }, "extensionData": [ [Function], ], "replaces": undefined, + "withContext": [Function], }, }, "kind": "api", diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 59a81f1b59..4996fbc535 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -216,6 +216,167 @@ describe('createExtension', () => { ); }); + it('should create an extension with relative attachment points', () => { + const extension = createExtension({ + attachTo: [ + { relative: {}, input: 'tabs' }, + { relative: { kind: 'page' }, input: 'tabs' }, + { relative: { name: 'index' }, input: 'tabs' }, + { relative: { kind: 'page', name: 'index' }, input: 'tabs' }, + ], + output: [stringDataRef], + factory: () => [stringDataRef('bar')], + }); + expect(String(extension)).toBe( + 'ExtensionDefinition{attachTo=@tabs+page:@tabs+/index@tabs+page:/index@tabs}', + ); + }); + + it('should create an extension with relative attachment points by reference', () => { + const baseOpts = { + attachTo: { id: 'root', input: 'children' }, + inputs: { + tabs: createExtensionInput([stringDataRef]), + }, + output: [], + factory: () => [], + }; + const parent1 = createExtension({ + ...baseOpts, + }); + const parent2 = createExtension({ + ...baseOpts, + kind: 'page', + }); + const parent3 = createExtension({ + ...baseOpts, + name: 'index', + }); + const parent4 = createExtension({ + ...baseOpts, + inputs: {}, + kind: 'page', + name: 'index', + }).override({ + inputs: { + otherTabs: createExtensionInput([stringDataRef]), + }, + factory: () => [], + }); + const extension = createExtension({ + attachTo: [ + parent1.inputs.tabs, + parent2.inputs.tabs, + parent3.inputs.tabs, + parent4.inputs.otherTabs, + ], + output: [stringDataRef], + factory: () => [stringDataRef('bar')], + }); + expect(String(extension)).toBe( + 'ExtensionDefinition{attachTo=@tabs+page:@tabs+/index@tabs+page:/index@otherTabs}', + ); + const overrdeExtension = extension.override({ + attachTo: [ + parent2.inputs.tabs, + parent3.inputs.tabs, + parent4.inputs.otherTabs, + ], + }); + expect(String(overrdeExtension)).toBe( + 'ExtensionDefinition{attachTo=page:@tabs+/index@tabs+page:/index@otherTabs}', + ); + }); + + it('should provide type safe attachments by reference', () => { + const parent = createExtension({ + attachTo: { id: 'root', input: 'children' }, + inputs: { + string: createExtensionInput([stringDataRef]), + stringOpt: createExtensionInput([stringDataRef.optional()]), + number: createExtensionInput([numberDataRef]), + numberOpt: createExtensionInput([numberDataRef.optional()]), + both: createExtensionInput([stringDataRef, numberDataRef]), + bothOptString: createExtensionInput([ + stringDataRef.optional(), + numberDataRef, + ]), + bothOptNumber: createExtensionInput([ + stringDataRef, + numberDataRef.optional(), + ]), + bothOpt: createExtensionInput([ + stringDataRef.optional(), + numberDataRef.optional(), + ]), + }, + output: [], + factory: () => [], + }); + const strOutExt = createExtension({ + attachTo: parent.inputs.string, + output: [stringDataRef], + factory: () => [stringDataRef('str')], + }); + strOutExt.override({ + attachTo: parent.inputs.string, + }); + strOutExt.override({ + attachTo: parent.inputs.stringOpt, + }); + strOutExt.override({ + // @ts-expect-error + attachTo: parent.inputs.number, + }); + strOutExt.override({ + attachTo: parent.inputs.numberOpt, + }); + strOutExt.override({ + // @ts-expect-error + attachTo: parent.inputs.both, + }); + strOutExt.override({ + attachTo: parent.inputs.bothOptNumber, + }); + strOutExt.override({ + // @ts-expect-error + attachTo: parent.inputs.bothOptString, + }); + strOutExt.override({ + attachTo: parent.inputs.bothOpt, + }); + const numberOutExt = createExtension({ + // @ts-expect-error + attachTo: parent.inputs.string, + output: [numberDataRef], + factory: () => [numberDataRef(1)], + }); + numberOutExt.override({ + // @ts-expect-error + attachTo: parent.inputs.string, + }); + numberOutExt.override({ + attachTo: parent.inputs.number, + }); + const bothOutExt = createExtension({ + attachTo: parent.inputs.both, + output: [numberDataRef, stringDataRef], + factory: () => [numberDataRef(1), stringDataRef('str')], + }); + // TODO(Rugvip): Potentially encapsulate the parent input type in the extension, until then we can't verify this + bothOutExt.override({ + output: [numberDataRef.optional(), stringDataRef], + factory: () => [stringDataRef('str')], + }); + bothOutExt.override({ + // @ts-expect-error + attachTo: parent.inputs.both, + output: [numberDataRef.optional(), stringDataRef], + factory: () => [stringDataRef('str')], + }); + expect('types').not.toBe('broken'); + }); + it('should create an extension with input', () => { const extension = createExtension({ attachTo: { id: 'root', input: 'default' }, diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 0c0b75a572..0fec40f4c9 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -20,7 +20,10 @@ import { ResolvedInputValueOverrides, resolveInputOverrides, } from './resolveInputOverrides'; -import { createExtensionDataContainer } from '@internal/frontend'; +import { + createExtensionDataContainer, + OpaqueExtensionInput, +} from '@internal/frontend'; import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef'; import { ExtensionInput } from './createExtensionInput'; import { z } from 'zod'; @@ -44,13 +47,12 @@ export const ctxParamsSymbol = Symbol('params'); * Convert a single extension input into a matching resolved input. * @public */ -export type ResolvedExtensionInput< - TExtensionInput extends ExtensionInput, -> = TExtensionInput['extensionData'] extends Array - ? { - node: AppNode; - } & ExtensionDataContainer - : never; +export type ResolvedExtensionInput = + TExtensionInput['extensionData'] extends Array + ? { + node: AppNode; + } & ExtensionDataContainer + : never; /** * Converts an extension input map into a matching collection of resolved inputs. @@ -58,7 +60,7 @@ export type ResolvedExtensionInput< */ export type ResolvedExtensionInputs< TInputs extends { - [name in string]: ExtensionInput; + [name in string]: ExtensionInput; }, > = { [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] @@ -91,50 +93,104 @@ type JoinStringUnion< : JoinStringUnion : TResult; +/** @ignore */ +export type RequiredExtensionIds = + UExtensionData extends any + ? UExtensionData['config']['optional'] extends true + ? never + : UExtensionData['id'] + : never; + /** @ignore */ export type VerifyExtensionFactoryOutput< UDeclaredOutput extends ExtensionDataRef, UFactoryOutput extends ExtensionDataValue, -> = ( - UDeclaredOutput extends any - ? UDeclaredOutput['config']['optional'] extends true - ? never - : UDeclaredOutput['id'] - : never -) extends infer IRequiredOutputIds - ? [IRequiredOutputIds] extends [UFactoryOutput['id']] - ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']] - ? {} - : `Error: The extension factory has undeclared output(s): ${JoinStringUnion< - Exclude - >}` - : `Error: The extension factory is missing the following output(s): ${JoinStringUnion< - Exclude +> = [RequiredExtensionIds] extends [UFactoryOutput['id']] + ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']] + ? {} + : `Error: The extension factory has undeclared output(s): ${JoinStringUnion< + Exclude >}` - : never; + : `Error: The extension factory is missing the following output(s): ${JoinStringUnion< + Exclude, UFactoryOutput['id']> + >}`; -/** @public */ -export type ExtensionAttachToSpec = - | { id: string; input: string } - | Array<{ id: string; input: string }>; +/** @ignore */ +export type VerifyExtensionAttachTo< + UOutput extends ExtensionDataRef, + UParentInput extends ExtensionDataRef, +> = ExtensionDataRef extends UParentInput + ? {} + : [RequiredExtensionIds] extends [RequiredExtensionIds] + ? {} + : `Error: This parent extension input requires the following extension data, but it is not declared as guaranteed output of this extension: ${JoinStringUnion< + Exclude, RequiredExtensionIds> + >}`; + +/** + * Specifies where an extension should attach in the extension tree. + * + * @remarks + * + * A standard attachment point declaration will specify the ID of the parent extension, as well as the name of the input to attach to. + * + * There are three more advanced forms that are available for more complex use-cases: + * + * 1. Relative attachment points: using the `relative` property instead of `id`, the attachment point is resolved relative to the current plugin. + * 2. Extension input references: using a reference in code to another extension's input in the same plugin. These references are always relative. + * 3. Array of attachment points: an array of attachment points can be used to clone and attach to multiple extensions at once. + * + * @example + * ```ts + * // Attach to a specific extension by full ID + * { id: 'app/routes', input: 'routes' } + * + * // Attach to an extension in the same plugin by kind + * { relative: { kind: 'page' }, input: 'actions' } + * + * // Attach to a specific input of another extension + * const page = ParentBlueprint.make({ ... }); + * const child = ChildBlueprint.make({ attachTo: page.inputs.children }); + * + * // Attach to multiple parents at once + * [ + * { id: 'page/home', input: 'widgets' }, + * { relative: { kind: 'page' }, input: 'widgets' }, + * ] + * ``` + * + * @public + */ +export type ExtensionDefinitionAttachTo< + UParentInputs extends ExtensionDataRef = ExtensionDataRef, +> = + | { id: string; input: string; relative?: never } + | { relative: { kind?: string; name?: string }; input: string; id?: never } + | ExtensionInput + | Array< + | { id: string; input: string; relative?: never } + | { + relative: { kind?: string; name?: string }; + input: string; + id?: never; + } + | ExtensionInput + >; /** @public */ export type CreateExtensionOptions< TKind extends string | undefined, TName extends string | undefined, UOutput extends ExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + TInputs extends { [inputName in string]: ExtensionInput }, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, + UParentInputs extends ExtensionDataRef, > = { kind?: TKind; name?: TName; - attachTo: ExtensionAttachToSpec; + attachTo: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo; disabled?: boolean; inputs?: TInputs; output: Array; @@ -158,12 +214,7 @@ export type ExtensionDefinitionParameters = { configInput?: { [K in string]: any }; config?: { [K in string]: any }; output?: ExtensionDataRef; - inputs?: { - [KName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; + inputs?: { [KName in string]: ExtensionInput }; params?: object | ExtensionBlueprintDefineParams; }; @@ -188,23 +239,34 @@ export type ExtensionDefinition< $$type: '@backstage/ExtensionDefinition'; readonly T: T; + /** + * References to the inputs of this extension, which can be used to attach child extensions. + */ + readonly inputs: { + [K in keyof T['inputs']]: ExtensionInput< + T['inputs'][K] extends ExtensionInput ? IData : never + >; + }; + override< TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, UNewOutput extends ExtensionDataRef, - TExtraInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + TExtraInputs extends { [inputName in string]: ExtensionInput }, TParamsInput extends AnyParamsInput>, + UParentInputs extends ExtensionDataRef, >( args: Expand< { - attachTo?: ExtensionAttachToSpec; + attachTo?: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo< + ExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, + UParentInputs + >; disabled?: boolean; inputs?: TExtraInputs & { [KName in keyof T['inputs']]?: `Error: Input '${KName & @@ -286,6 +348,30 @@ export type ExtensionDefinition< }>; }; +/** + * @internal + */ +function bindInputs( + inputs: { [inputName in string]: ExtensionInput } | undefined, + kind?: string, + name?: string, +) { + if (!inputs) { + return {}; + } + + return Object.fromEntries( + Object.entries(inputs).map(([inputName, input]) => [ + inputName, + OpaqueExtensionInput.toInternal(input).withContext({ + kind, + name, + input: inputName, + }), + ]), + ); +} + /** * Creates a new extension definition for installation in a Backstage app. * @@ -323,16 +409,12 @@ export type ExtensionDefinition< */ export function createExtension< UOutput extends ExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + TInputs extends { [inputName in string]: ExtensionInput }, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined, + UParentInputs extends ExtensionDataRef = ExtensionDataRef, >( options: CreateExtensionOptions< TKind, @@ -340,7 +422,8 @@ export function createExtension< UOutput, TInputs, TConfigSchema, - UFactoryOutput + UFactoryOutput, + UParentInputs >, ): ExtensionDefinition<{ config: string extends keyof TConfigSchema @@ -404,7 +487,7 @@ export function createExtension< name: options.name, attachTo: options.attachTo, disabled: options.disabled ?? false, - inputs: options.inputs ?? {}, + inputs: bindInputs(options.inputs, options.kind, options.name), output: options.output, configSchema, factory: options.factory, @@ -416,12 +499,41 @@ export function createExtension< if (options.name) { parts.push(`name=${options.name}`); } - parts.push( - `attachTo=${[options.attachTo] - .flat() - .map(a => `${a.id}@${a.input}`) - .join('+')}`, - ); + const attachTo = [options.attachTo] + .flat() + .map(aAny => { + const a = aAny as ExtensionDefinitionAttachTo; + if (OpaqueExtensionInput.isType(a)) { + const { context } = OpaqueExtensionInput.toInternal(a); + if (!context) { + return ''; + } + let id = ''; + if (context?.kind) { + id = `${context?.kind}:${id}`; + } + if (context?.name) { + id = `${id}/${context?.name}`; + } + return `${id}@${context.input}`; + } + if ('relative' in a && a.relative) { + let id = ''; + if (a.relative.kind) { + id = `${a.relative.kind}:${id}`; + } + if (a.relative.name) { + id = `${id}/${a.relative.name}`; + } + return `${id}@${a.input}`; + } + if ('id' in a) { + return `${a.id}@${a.input}`; + } + throw new Error('Invalid attachment point specification'); + }) + .join('+'); + parts.push(`attachTo=${attachTo}`); return `ExtensionDefinition{${parts.join(',')}}`; }, override(overrideOptions) { @@ -449,9 +561,17 @@ export function createExtension< return createExtension({ kind: options.kind, name: options.name, - attachTo: overrideOptions.attachTo ?? options.attachTo, + attachTo: (overrideOptions.attachTo ?? + options.attachTo) as ExtensionDefinitionAttachTo, disabled: overrideOptions.disabled ?? options.disabled, - inputs: { ...overrideOptions.inputs, ...options.inputs }, + inputs: bindInputs( + { + ...(options.inputs ?? {}), + ...(overrideOptions.inputs ?? {}), + }, + options.kind, + options.name, + ), output: (overrideOptions.output ?? options.output) as ExtensionDataRef[], config: diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index e4cc876ff0..4759441187 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -30,7 +30,7 @@ import { } from './createExtensionDataRef'; import { createExtensionInput } from './createExtensionInput'; import { RouteRef } from '../routing'; -import { ExtensionDefinition } from './createExtension'; +import { createExtension, ExtensionDefinition } from './createExtension'; import { createExtensionDataContainer, OpaqueExtensionDefinition, @@ -1345,6 +1345,235 @@ describe('createExtensionBlueprint', () => { ).toThrow('Refused to override params and factory at the same time'); }); + describe('with relative attachment points', () => { + const dataRef = createExtensionDataRef().with({ id: 'test.data' }); + + it('should create an extension with relative attachment points', () => { + const blueprint = createExtensionBlueprint({ + kind: 'test', + attachTo: [ + { relative: {}, input: 'tabs' }, + { relative: { kind: 'page' }, input: 'tabs' }, + { relative: { name: 'index' }, input: 'tabs' }, + { relative: { kind: 'page', name: 'index' }, input: 'tabs' }, + ], + output: [dataRef], + factory: () => [dataRef('bar')], + }); + + expect(String(blueprint.make({ params: {} }))).toBe( + 'ExtensionDefinition{kind=test,attachTo=@tabs+page:@tabs+/index@tabs+page:/index@tabs}', + ); + expect( + String( + blueprint.make({ + attachTo: [ + { relative: { kind: 'page' }, input: 'tabs' }, + { relative: { name: 'index' }, input: 'tabs' }, + { relative: { kind: 'page', name: 'index' }, input: 'tabs' }, + ], + params: {}, + }), + ), + ).toBe( + 'ExtensionDefinition{kind=test,attachTo=page:@tabs+/index@tabs+page:/index@tabs}', + ); + expect( + String( + blueprint.makeWithOverrides({ + attachTo: { + relative: { kind: 'page', name: 'index' }, + input: 'tabs', + }, + factory: orig => orig({}), + }), + ), + ).toBe( + 'ExtensionDefinition{kind=test,attachTo=page:/index@tabs}', + ); + }); + + it('should create an extension with relative attachment points by reference', () => { + const baseOpts = { + attachTo: { id: 'root', input: 'children' }, + inputs: { + tabs: createExtensionInput([dataRef]), + }, + output: [], + factory: () => [], + }; + const parent1 = createExtension({ + ...baseOpts, + }); + const parent2 = createExtension({ + ...baseOpts, + kind: 'page', + }); + const parent3 = createExtension({ + ...baseOpts, + name: 'index', + }); + const parent4 = createExtension({ + ...baseOpts, + inputs: {}, + kind: 'page', + name: 'index', + }).override({ + inputs: { + otherTabs: createExtensionInput([dataRef]), + }, + factory: () => [], + }); + const blueprint = createExtensionBlueprint({ + kind: 'test', + attachTo: [ + parent1.inputs.tabs, + parent2.inputs.tabs, + parent3.inputs.tabs, + parent4.inputs.otherTabs, + ], + output: [dataRef], + factory: () => [dataRef('bar')], + }); + expect(String(blueprint.make({ params: {} }))).toBe( + 'ExtensionDefinition{kind=test,attachTo=@tabs+page:@tabs+/index@tabs+page:/index@otherTabs}', + ); + expect( + String( + blueprint.make({ + attachTo: [ + parent2.inputs.tabs, + parent3.inputs.tabs, + parent4.inputs.otherTabs, + ], + params: {}, + }), + ), + ).toBe( + 'ExtensionDefinition{kind=test,attachTo=page:@tabs+/index@tabs+page:/index@otherTabs}', + ); + expect( + String( + blueprint.makeWithOverrides({ + attachTo: parent4.inputs.otherTabs, + factory: orig => orig({}), + }), + ), + ).toBe( + 'ExtensionDefinition{kind=test,attachTo=page:/index@otherTabs}', + ); + }); + + it('should provide type safe attachments by reference', () => { + const stringDataRef = createExtensionDataRef().with({ + id: 'test.string', + }); + const numberDataRef = createExtensionDataRef().with({ + id: 'test.number', + }); + + const parent = createExtensionBlueprint({ + kind: 'test-parent', + attachTo: { id: 'root', input: 'children' }, + inputs: { + string: createExtensionInput([stringDataRef]), + stringOpt: createExtensionInput([stringDataRef.optional()]), + number: createExtensionInput([numberDataRef]), + numberOpt: createExtensionInput([numberDataRef.optional()]), + both: createExtensionInput([stringDataRef, numberDataRef]), + bothOptString: createExtensionInput([ + stringDataRef.optional(), + numberDataRef, + ]), + bothOptNumber: createExtensionInput([ + stringDataRef, + numberDataRef.optional(), + ]), + bothOpt: createExtensionInput([ + stringDataRef.optional(), + numberDataRef.optional(), + ]), + }, + output: [], + factory: () => [], + }).make({ params: {} }); + const strOutExt = createExtensionBlueprint({ + kind: 'test', + attachTo: parent.inputs.string, + output: [stringDataRef], + factory: () => [stringDataRef('str')], + }); + strOutExt.make({ + attachTo: parent.inputs.string, + params: {}, + }); + strOutExt.makeWithOverrides({ + attachTo: parent.inputs.stringOpt, + factory: orig => orig({}), + }); + strOutExt.make({ + // @ts-expect-error + attachTo: parent.inputs.number, + params: {}, + }); + strOutExt.makeWithOverrides({ + attachTo: parent.inputs.numberOpt, + factory: orig => orig({}), + }); + strOutExt.make({ + // @ts-expect-error + attachTo: parent.inputs.both, + params: {}, + }); + strOutExt.make({ + attachTo: parent.inputs.bothOptNumber, + params: {}, + }); + strOutExt.make({ + // @ts-expect-error + attachTo: parent.inputs.bothOptString, + params: {}, + }); + strOutExt.make({ + attachTo: parent.inputs.bothOpt, + params: {}, + }); + const numberOutExt = createExtensionBlueprint({ + kind: 'test', + // @ts-expect-error + attachTo: parent.inputs.string, + output: [numberDataRef], + factory: () => [numberDataRef(1)], + }); + numberOutExt.make({ + // @ts-expect-error + attachTo: parent.inputs.string, + params: {}, + }); + numberOutExt.makeWithOverrides({ + attachTo: parent.inputs.number, + factory: orig => orig({}), + }); + const bothOutExt = createExtensionBlueprint({ + kind: 'test', + attachTo: parent.inputs.both, + output: [numberDataRef, stringDataRef], + factory: () => [numberDataRef(1), stringDataRef('str')], + }); + bothOutExt.makeWithOverrides({ + output: [numberDataRef.optional(), stringDataRef], + factory: orig => orig({}), + }); + bothOutExt.makeWithOverrides({ + // @ts-expect-error + attachTo: parent.inputs.both, + output: [numberDataRef.optional(), stringDataRef], + factory: orig => orig({}), + }); + expect('types').not.toBe('broken'); + }); + }); + describe('with advanced parameter types', () => { const testDataRef = createExtensionDataRef().with({ id: 'test' }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 1a24eed712..f9a3731743 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -18,12 +18,13 @@ import { ApiHolder, AppNode } from '../apis'; import { Expand } from '@backstage/types'; import { OpaqueType } from '@internal/opaque'; import { - ExtensionAttachToSpec, + ExtensionDefinitionAttachTo, ExtensionDefinition, ResolvedExtensionInputs, VerifyExtensionFactoryOutput, createExtension, ctxParamsSymbol, + VerifyExtensionAttachTo, } from './createExtension'; import { z } from 'zod'; import { ExtensionInput } from './createExtensionInput'; @@ -103,18 +104,15 @@ export type CreateExtensionBlueprintOptions< TKind extends string, TParams extends object | ExtensionBlueprintDefineParams, UOutput extends ExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + TInputs extends { [inputName in string]: ExtensionInput }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, TDataRefs extends { [name in string]: ExtensionDataRef }, + UParentInputs extends ExtensionDataRef, > = { kind: TKind; - attachTo: ExtensionAttachToSpec; + attachTo: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo; disabled?: boolean; inputs?: TInputs; output: Array; @@ -186,12 +184,7 @@ export type ExtensionBlueprintParameters = { configInput?: { [K in string]: any }; config?: { [K in string]: any }; output?: ExtensionDataRef; - inputs?: { - [KName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; + inputs?: { [KName in string]: ExtensionInput }; dataRefs?: { [name in string]: ExtensionDataRef }; }; @@ -222,9 +215,11 @@ export interface ExtensionBlueprint< make< TName extends string | undefined, TParamsInput extends AnyParamsInput>, + UParentInputs extends ExtensionDataRef, >(args: { name?: TName; - attachTo?: ExtensionAttachToSpec; + attachTo?: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo, UParentInputs>; disabled?: boolean; params: TParamsInput extends ExtensionBlueprintDefineParams ? TParamsInput @@ -254,15 +249,17 @@ export interface ExtensionBlueprint< }, UFactoryOutput extends ExtensionDataValue, UNewOutput extends ExtensionDataRef, - TExtraInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + TExtraInputs extends { [inputName in string]: ExtensionInput }, + UParentInputs extends ExtensionDataRef, >(args: { name?: TName; - attachTo?: ExtensionAttachToSpec; + attachTo?: ExtensionDefinitionAttachTo & + VerifyExtensionAttachTo< + ExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, + UParentInputs + >; disabled?: boolean; inputs?: TExtraInputs & { [KName in keyof T['inputs']]?: `Error: Input '${KName & @@ -455,15 +452,11 @@ function unwrapParams( export function createExtensionBlueprint< TParams extends object | ExtensionBlueprintDefineParams, UOutput extends ExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + TInputs extends { [inputName in string]: ExtensionInput }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, TKind extends string, + UParentInputs extends ExtensionDataRef, TDataRefs extends { [name in string]: ExtensionDataRef } = never, >( options: CreateExtensionBlueprintOptions< @@ -473,7 +466,8 @@ export function createExtensionBlueprint< TInputs, TConfigSchema, UFactoryOutput, - TDataRefs + TDataRefs, + UParentInputs >, ): ExtensionBlueprint<{ kind: TKind; @@ -509,7 +503,8 @@ export function createExtensionBlueprint< return createExtension({ kind: options.kind, name: args.name, - attachTo: args.attachTo ?? options.attachTo, + attachTo: (args.attachTo ?? + options.attachTo) as ExtensionDefinitionAttachTo, disabled: args.disabled ?? options.disabled, inputs: options.inputs, output: options.output as ExtensionDataRef[], @@ -525,7 +520,8 @@ export function createExtensionBlueprint< return createExtension({ kind: options.kind, name: args.name, - attachTo: args.attachTo ?? options.attachTo, + attachTo: (args.attachTo ?? + options.attachTo) as ExtensionDefinitionAttachTo, disabled: args.disabled ?? options.disabled, inputs: { ...args.inputs, ...options.inputs }, output: (args.output ?? options.output) as ExtensionDataRef[], diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts index 084758b793..8511f79b4e 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { OpaqueExtensionInput } from '@internal/frontend'; import { createExtensionDataRef } from './createExtensionDataRef'; import { ExtensionInput, createExtensionInput } from './createExtensionInput'; @@ -29,6 +30,7 @@ describe('createExtensionInput', () => { $$type: '@backstage/ExtensionInput', extensionData: [stringDataRef, numberDataRef], config: { singleton: false, optional: false }, + withContext: expect.any(Function), }); const x1: ExtensionInput< @@ -54,6 +56,20 @@ describe('createExtensionInput', () => { unused(x1, x2, x3, x4); }); + it('should attach a context to the input', () => { + const input = createExtensionInput([stringDataRef, numberDataRef]); + const context = { input: 'test1', kind: 'test2', name: 'test3' }; + const inputWithContext = + OpaqueExtensionInput.toInternal(input).withContext(context); + expect(inputWithContext).toEqual({ + $$type: '@backstage/ExtensionInput', + extensionData: [stringDataRef, numberDataRef], + config: { singleton: false, optional: false }, + withContext: expect.any(Function), + context, + }); + }); + it('should create a singleton input', () => { const input = createExtensionInput([stringDataRef, numberDataRef], { singleton: true, @@ -62,6 +78,7 @@ describe('createExtensionInput', () => { $$type: '@backstage/ExtensionInput', extensionData: [stringDataRef, numberDataRef], config: { singleton: true, optional: false }, + withContext: expect.any(Function), }); const x1: ExtensionInput< @@ -96,6 +113,7 @@ describe('createExtensionInput', () => { $$type: '@backstage/ExtensionInput', extensionData: [stringDataRef, numberDataRef], config: { singleton: true, optional: true }, + withContext: expect.any(Function), }); const x1: ExtensionInput< diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts index 7209e6f647..57040c8adf 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts @@ -14,17 +14,28 @@ * limitations under the License. */ +import { + ExtensionInputContext, + OpaqueExtensionInput, +} from '@internal/frontend'; import { ExtensionDataRef } from './createExtensionDataRef'; /** @public */ export interface ExtensionInput< - UExtensionData extends ExtensionDataRef, - TConfig extends { singleton: boolean; optional: boolean }, + UExtensionData extends ExtensionDataRef< + unknown, + string, + { optional?: true } + > = ExtensionDataRef, + TConfig extends { singleton: boolean; optional: boolean } = { + singleton: boolean; + optional: boolean; + }, > { - $$type: '@backstage/ExtensionInput'; - extensionData: Array; - config: TConfig; - replaces?: Array<{ id: string; input: string }>; + readonly $$type: '@backstage/ExtensionInput'; + readonly extensionData: Array; + readonly config: TConfig; + readonly replaces?: Array<{ id: string; input: string }>; } /** @public */ @@ -61,8 +72,7 @@ export function createExtensionInput< } } } - return { - $$type: '@backstage/ExtensionInput', + const baseOptions = { extensionData, config: { singleton: Boolean(config?.singleton) as TConfig['singleton'] extends true @@ -73,11 +83,21 @@ export function createExtensionInput< : false, }, replaces: config?.replaces, - } as ExtensionInput< + }; + + function createInstance(parent?: ExtensionInputContext): ExtensionInput< UExtensionData, { singleton: TConfig['singleton'] extends true ? true : false; optional: TConfig['optional'] extends true ? true : false; } - >; + > { + return OpaqueExtensionInput.createInstance(undefined, { + ...baseOptions, + context: parent, + withContext: createInstance, + }); + } + + return createInstance(); } diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index 45c80d4a90..1bbdf68b13 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -18,8 +18,8 @@ export { coreExtensionData } from './coreExtensionData'; export { createExtension, type ExtensionDefinition, + type ExtensionDefinitionAttachTo, type ExtensionDefinitionParameters, - type ExtensionAttachToSpec, type CreateExtensionOptions, type ResolvedExtensionInput, type ResolvedExtensionInputs, @@ -54,7 +54,11 @@ export { type FrontendFeatureLoader, type CreateFrontendFeatureLoaderOptions, } from './createFrontendFeatureLoader'; -export { type Extension } from './resolveExtensionDefinition'; +export { + type Extension, + type ExtensionAttachTo, + type ExtensionAttachToSpec, +} from './resolveExtensionDefinition'; export { type ExtensionDataContainer, type FeatureFlagConfig, diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts index a74d908024..d8b90d69f3 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts @@ -14,11 +14,21 @@ * limitations under the License. */ +import { + createExtensionDataRef, + createExtensionInput, +} from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from './createExtension'; import { ResolveExtensionId, resolveExtensionDefinition, } from './resolveExtensionDefinition'; +import { + OpaqueExtensionDefinition, + OpaqueExtensionInput, +} from '@internal/frontend'; + +const testDataRef = createExtensionDataRef().with({ id: 'test' }); describe('resolveExtensionDefinition', () => { const baseDef = { @@ -26,6 +36,7 @@ describe('resolveExtensionDefinition', () => { T: undefined as any, version: 'v2', attachTo: { id: '', input: '' }, + inputs: {}, disabled: false, override: () => ({} as ExtensionDefinition), }; @@ -60,6 +71,111 @@ describe('resolveExtensionDefinition', () => { 'Extension must declare an explicit namespace or name as it could not be resolved from context, kind=undefined namespace=undefined name=undefined', ); }); + + it('should resolve extension input references', () => { + const baseInpuf = OpaqueExtensionInput.toInternal( + createExtensionInput([testDataRef]), + ); + expect( + resolveExtensionDefinition( + OpaqueExtensionDefinition.toInternal({ + ...baseDef, + attachTo: baseInpuf.withContext({ + kind: 'parent', + name: 'example', + input: 'children', + }), + }), + { namespace: 'test' }, + ).attachTo, + ).toEqual({ + id: 'parent:test/example', + input: 'children', + }); + + expect( + resolveExtensionDefinition( + OpaqueExtensionDefinition.toInternal({ + ...baseDef, + attachTo: baseInpuf.withContext({ + name: 'example', + input: 'children', + }), + }), + { namespace: 'test' }, + ).attachTo, + ).toEqual({ + id: 'test/example', + input: 'children', + }); + + expect( + resolveExtensionDefinition( + OpaqueExtensionDefinition.toInternal({ + ...baseDef, + attachTo: baseInpuf.withContext({ + kind: 'parent', + input: 'children', + }), + }), + { namespace: 'test' }, + ).attachTo, + ).toEqual({ + id: 'parent:test', + input: 'children', + }); + + expect( + resolveExtensionDefinition( + OpaqueExtensionDefinition.toInternal({ + ...baseDef, + attachTo: baseInpuf.withContext({ + input: 'children', + }), + }), + { namespace: 'test' }, + ).attachTo, + ).toEqual({ + id: 'test', + input: 'children', + }); + + expect( + resolveExtensionDefinition( + OpaqueExtensionDefinition.toInternal({ + ...baseDef, + attachTo: [ + baseInpuf.withContext({ + kind: 'k1', + input: 'children', + }), + baseInpuf.withContext({ + kind: 'k2', + input: 'children', + }), + baseInpuf.withContext({ + kind: 'k3', + input: 'children', + }), + ], + }), + { namespace: 'test' }, + ).attachTo, + ).toEqual([ + { + id: 'k1:test', + input: 'children', + }, + { + id: 'k2:test', + input: 'children', + }, + { + id: 'k3:test', + input: 'children', + }, + ]); + }); }); describe('old resolveExtensionDefinition', () => { @@ -68,6 +184,7 @@ describe('old resolveExtensionDefinition', () => { T: undefined as any, version: 'v1', attachTo: { id: '', input: '' }, + inputs: {}, disabled: false, override: () => ({} as ExtensionDefinition), }; diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts index a5b6859e1a..f99d586e87 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts @@ -16,7 +16,7 @@ import { ApiHolder, AppNode } from '../apis'; import { - ExtensionAttachToSpec, + ExtensionDefinitionAttachTo, ExtensionDefinition, ExtensionDefinitionParameters, ResolvedExtensionInputs, @@ -24,7 +24,21 @@ import { import { PortableSchema } from '../schema'; import { ExtensionInput } from './createExtensionInput'; import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef'; -import { OpaqueExtensionDefinition } from '@internal/frontend'; +import { + OpaqueExtensionDefinition, + OpaqueExtensionInput, +} from '@internal/frontend'; + +/** @public */ +export type ExtensionAttachTo = + | { id: string; input: string } + | Array<{ id: string; input: string }>; + +/** + * @deprecated Use {@link ExtensionAttachTo} instead. + * @public + */ +export type ExtensionAttachToSpec = ExtensionAttachTo; /** @public */ export interface Extension { @@ -68,22 +82,14 @@ export type InternalExtension = Extension< } | { readonly version: 'v2'; - readonly inputs: { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; + readonly inputs: { [inputName in string]: ExtensionInput }; readonly output: Array; factory(options: { apis: ApiHolder; node: AppNode; config: TConfig; inputs: ResolvedExtensionInputs<{ - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; + [inputName in string]: ExtensionInput; }>; }): Iterable>; } @@ -126,24 +132,11 @@ export type ResolveExtensionId< : never : never; -/** @internal */ -export function resolveExtensionDefinition< - T extends ExtensionDefinitionParameters, ->( - definition: ExtensionDefinition, - context?: { namespace?: string }, -): Extension { - const internalDefinition = OpaqueExtensionDefinition.toInternal(definition); - const { - name, - kind, - namespace: _skip1, - override: _skip2, - ...rest - } = internalDefinition; - - const namespace = internalDefinition.namespace ?? context?.namespace; - +function resolveExtensionId( + kind?: string, + namespace?: string, + name?: string, +): string { const namePart = name && namespace ? `${namespace}/${name}` : namespace || name; if (!namePart) { @@ -152,10 +145,75 @@ export function resolveExtensionDefinition< ); } - const id = kind ? `${kind}:${namePart}` : namePart; + return kind ? `${kind}:${namePart}` : namePart; +} + +function resolveAttachTo( + attachTo: ExtensionDefinitionAttachTo, + namespace?: string, +): ExtensionAttachToSpec { + const resolveSpec = ( + spec: Exclude>, + ): { id: string; input: string } => { + if (OpaqueExtensionInput.isType(spec)) { + const { context } = OpaqueExtensionInput.toInternal(spec); + if (!context) { + throw new Error( + 'Invalid input object without a parent extension used as attachment point', + ); + } + return { + id: resolveExtensionId(context.kind, namespace, context.name), + input: context.input, + }; + } + if ('relative' in spec && spec.relative) { + return { + id: resolveExtensionId( + spec.relative.kind, + namespace, + spec.relative.name, + ), + input: spec.input, + }; + } + if ('id' in spec) { + return { id: spec.id, input: spec.input }; + } + throw new Error('Invalid attachment point specification'); + }; + + if (Array.isArray(attachTo)) { + return attachTo.map(resolveSpec); + } + + return resolveSpec(attachTo); +} + +/** @internal */ +export function resolveExtensionDefinition< + T extends ExtensionDefinitionParameters, +>( + definition: ExtensionDefinition, + context?: { namespace?: string }, +): Extension { + const internalDefinition = OpaqueExtensionDefinition.toInternal(definition); + + const { + name, + kind, + namespace: internalNamespace, + override: _skip2, + attachTo, + ...rest + } = internalDefinition; + + const namespace = internalNamespace ?? context?.namespace; + const id = resolveExtensionId(kind, namespace, name); return { ...rest, + attachTo: resolveAttachTo(attachTo, namespace), $$type: '@backstage/Extension', version: internalDefinition.version, id, diff --git a/packages/frontend-plugin-api/src/wiring/resolveInputOverrides.ts b/packages/frontend-plugin-api/src/wiring/resolveInputOverrides.ts index 8ffec893ee..b46bb426fa 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveInputOverrides.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveInputOverrides.ts @@ -19,7 +19,6 @@ import { Expand } from '@backstage/types'; import { ResolvedExtensionInput } from './createExtension'; import { createExtensionDataContainer } from '@internal/frontend'; import { - ExtensionDataRef, ExtensionDataRefToValue, ExtensionDataValue, } from './createExtensionDataRef'; @@ -28,16 +27,8 @@ import { ExtensionDataContainer } from './types'; /** @ignore */ export type ResolvedInputValueOverrides< - TInputs extends { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - } = { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; + TInputs extends { [inputName in string]: ExtensionInput } = { + [inputName in string]: ExtensionInput; }, > = Expand< { @@ -90,12 +81,7 @@ function expectItem(value: T | T[]): T { /** @internal */ export function resolveInputOverrides( - declaredInputs?: { - [inputName in string]: ExtensionInput< - ExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + declaredInputs?: { [inputName in string]: ExtensionInput }, inputs?: { [KName in string]?: | ({ node: AppNode } & ExtensionDataContainer) diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index c85546dd9d..d9ef90fe21 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/repo-tools +## 0.16.0-next.2 + +### Minor Changes + +- 11c61f2: The `package-docs` command will now automatically use a `typedoc.json` file if one exists at the root of your project. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.2 + +## 0.15.4-next.1 + +### Patch Changes + +- 8f56eae: Updated knip-reports to detect dependencies in dev/alpha pattern +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + ## 0.15.4-next.0 ### Patch Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index f3789e14c1..b250018017 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/repo-tools", - "version": "0.15.4-next.0", + "version": "0.16.0-next.2", "description": "CLI for Backstage repo tooling ", "backstage": { "role": "cli" diff --git a/packages/repo-tools/src/commands/knip-reports/knip-extractor.ts b/packages/repo-tools/src/commands/knip-reports/knip-extractor.ts index 68bb0a9835..af3e32d2f4 100644 --- a/packages/repo-tools/src/commands/knip-reports/knip-extractor.ts +++ b/packages/repo-tools/src/commands/knip-reports/knip-extractor.ts @@ -58,7 +58,7 @@ async function generateKnipConfig({ knipConfigPath }: KnipConfigOptions) { workspaces: { '.': {}, '{packages,plugins}/*': { - entry: ['dev/index.{ts,tsx}', 'src/index.{ts,tsx}'], + entry: ['dev/**/*.{ts,tsx}', 'src/index.{ts,tsx}'], ignore: [ '.eslintrc.js', 'config.d.ts', diff --git a/packages/repo-tools/src/commands/package-docs/command.ts b/packages/repo-tools/src/commands/package-docs/command.ts index 174a1d949d..28255193f0 100644 --- a/packages/repo-tools/src/commands/package-docs/command.ts +++ b/packages/repo-tools/src/commands/package-docs/command.ts @@ -23,6 +23,7 @@ import { mkdirp } from 'fs-extra'; import { PackageDocsCache } from './Cache'; import { Lockfile } from '@backstage/cli-node'; import { glob } from 'glob'; +import { existsSync } from 'fs'; const limit = pLimit(8); @@ -220,6 +221,9 @@ export default async function packageDocs(paths: string[] = [], opts: any) { ...HIGHLIGHT_LANGUAGES.flatMap(e => ['--highlightLanguages', e]), '--out', cliPaths.resolveTargetRoot('type-docs'), + ...(existsSync(cliPaths.resolveTargetRoot('typedoc.json')) + ? ['--options', cliPaths.resolveTargetRoot('typedoc.json')] + : []), ].join(' '), { cwd: cliPaths.targetRoot, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index adc7acaab5..3fe53ec2d6 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,25 @@ # techdocs-cli-embedded-app +## 0.2.114-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + +## 0.2.114-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + ## 0.2.114-next.0 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index fa2cdf9dfb..024d8039cd 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,6 +1,6 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.114-next.0", + "version": "0.2.114-next.2", "backstage": { "role": "frontend" }, diff --git a/packages/techdocs-cli-embedded-app/public/index.html b/packages/techdocs-cli-embedded-app/public/index.html index 18bb3f50a9..196c711417 100644 --- a/packages/techdocs-cli-embedded-app/public/index.html +++ b/packages/techdocs-cli-embedded-app/public/index.html @@ -4,6 +4,7 @@ + ({ }, })); -enum Themes { - LIGHT = 'light', - DARK = 'dark', -} +const Themes = { + LIGHT: 'light', + DARK: 'dark', +} as const; export const TechDocsThemeToggle = () => { const appThemeApi = useApi(appThemeApiRef); const classes = useStyles(); - const [theme, setTheme] = useState( + const [theme, setTheme] = useState<(typeof Themes)[keyof typeof Themes]>( appThemeApi.getActiveThemeId() === Themes.DARK ? Themes.DARK : Themes.LIGHT, ); diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index bf8755612c..5f978adada 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,6 +1,6 @@ { "name": "@techdocs/cli", - "version": "1.10.1-next.0", + "version": "1.10.2-next.0", "description": "Utility CLI for managing TechDocs sites in Backstage.", "backstage": { "role": "cli" diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md index 2eec31def7..7347058a0c 100644 --- a/packages/ui/CHANGELOG.md +++ b/packages/ui/CHANGELOG.md @@ -1,5 +1,178 @@ # @backstage/ui +## 0.9.0-next.3 + +### Minor Changes + +- 83c100e: **BREAKING**: Removed `Collapsible` component. Migrate to `Accordion` or use React Aria `Disclosure`. + + ## Migration Path 1: Accordion (Opinionated Styled Component) + + Accordion provides preset styling with a similar component structure. + + ```diff + - import { Collapsible } from '@backstage/ui'; + + import { Accordion, AccordionTrigger, AccordionPanel } from '@backstage/ui'; + + - + - } /> + - Content + - + + + + + + + Content + + + ``` + + CSS classes: `.bui-CollapsibleRoot` → `.bui-Accordion`, `.bui-CollapsibleTrigger` → `.bui-AccordionTrigger` (now on heading element), `.bui-CollapsiblePanel` → `.bui-AccordionPanel` + + ## Migration Path 2: React Aria Disclosure (Full Customization) + + For custom styling without preset styles: + + ```tsx + import { Disclosure, Button, DisclosurePanel } from 'react-aria-components'; + + + + Content + ; + ``` + +- 816af0f: **BREAKING**: The `SelectProps` interface now accepts a generic type parameter for selection mode. + + Added searchable and multiple selection support to Select component. The component now accepts `searchable`, `selectionMode`, and `searchPlaceholder` props to enable filtering and multi-selection modes. + + Migration: If you're using `SelectProps` type directly, update from `SelectProps` to `SelectProps<'single' | 'multiple'>`. Component usage remains backward compatible. + +### Patch Changes + +- 35a3614: Fixed CSS issues in Select component including popover width constraints, focus outline behavior, and overflow handling. +- 01476f0: Improved visual consistency of PasswordField, SearchField, and MenuAutocomplete components. +- 836b0c7: Fixed dialog backdrop appearance in dark mode. +- 6d35a6b: Removed `@base-ui-components/react` dependency as all components now use React Aria Components. +- 7839e7b: Added `loading` prop to Button and ButtonIcon components for displaying spinner during async operations. +- a00fb88: Fixed Table Row component to properly support opening links in new tabs via right-click or Cmd+Click when using the href prop. + +## 0.9.0-next.2 + +### Minor Changes + +- 539cf26: **BREAKING**: Migrated Avatar component from Base UI to custom implementation with size changes: + + - Base UI-specific props are no longer supported + - Size values have been updated: + - New `x-small` size added (1.25rem / 20px) + - `small` size unchanged (1.5rem / 24px) + - `medium` size unchanged (2rem / 32px, default) + - `large` size **changed from 3rem to 2.5rem** (40px) + - New `x-large` size added (3rem / 48px) + + Migration: + + ```diff + # Remove Base UI-specific props + - + + + + # Update large size usage to x-large for same visual size + - + + + ``` + + Added `purpose` prop for accessibility control (`'informative'` or `'decoration'`). + +- 134151f: Fixing styles on SearchField in Backstage UI after migration to CSS modules. `SearchField` has now its own set of class names. We previously used class names from `TextField` but this approach was creating some confusion so going forward in your theme you'll be able to theme `TextField` and `SearchField` separately. + +### Patch Changes + +- d01de00: Fix broken external links in Backstage UI Header component. +- deaa427: Fixed Text component to prevent `truncate` prop from being spread to the underlying DOM element. +- 1059f95: Improved the Link component structure in Backstage UI. +- 6874094: Migrated CellProfile component from Base UI Avatar to Backstage UI Avatar component. +- 719d772: Avatar components in x-small and small sizes now display only one initial instead of two, improving readability at smaller dimensions. +- 3b18d80: Fixed RadioGroup radio button ellipse distortion by preventing flex shrink and grow. +- e16ece5: Set the color-scheme property depending on theme + +## 0.9.0-next.1 + +### Minor Changes + +- 5c614ff: **BREAKING**: Migrated Checkbox component from Base UI to React Aria Components. + + API changes required: + + - `checked` → `isSelected` + - `defaultChecked` → `defaultSelected` + - `disabled` → `isDisabled` + - `required` → `isRequired` + - `label` prop removed - use `children` instead + - CSS: `bui-CheckboxLabel` class removed + - Data attribute: `data-checked` → `data-selected` + - Use without label is no longer supported + + Migration examples: + + Before: + + ```tsx + + ``` + + After: + + ```tsx + + Accept terms + + ``` + + Before: + + ```tsx + + ``` + + After: + + ```tsx + Option + ``` + + Before: + + ```tsx + + ``` + + After: + + ```tsx + + Accessible label + + ``` + +- b78fc45: **BREAKING**: Changed className prop behavior to augment default styles instead of being ignored or overriding them. + + Affected components: + + - Menu, MenuListBox, MenuAutocomplete, MenuAutocompleteListbox, MenuItem, MenuListBoxItem, MenuSection, MenuSeparator + - Switch + - Skeleton + - FieldLabel + - Header, HeaderToolbar + - HeaderPage + - Tabs, TabList, Tab, TabPanel + + If you were passing custom className values to any of these components that relied on the previous behavior, you may need to adjust your styles to account for the default classes now being applied alongside your custom classes. + +### Patch Changes + +- ff9f0c3: Enable tree-shaking of imports other than `*.css`. +- 1ef3ca4: Added new VisuallyHidden component for hiding content visually while keeping it accessible to screen readers. + ## 0.8.2-next.0 ### Patch Changes diff --git a/packages/ui/css/styles.css b/packages/ui/css/styles.css index 862de8e0e3..c96eda05c9 100644 --- a/packages/ui/css/styles.css +++ b/packages/ui/css/styles.css @@ -247,6 +247,14 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + + [data-theme-mode="dark"] { + color-scheme: dark; + } + + [data-theme-mode="light"] { + color-scheme: light; + } } @layer components; diff --git a/packages/ui/package.json b/packages/ui/package.json index 10fb72840f..767af01601 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/ui", - "version": "0.8.2-next.0", + "version": "0.9.0-next.3", "backstage": { "role": "web-library" }, @@ -19,7 +19,9 @@ "directory": "packages/ui" }, "license": "Apache-2.0", - "sideEffects": true, + "sideEffects": [ + "*.css" + ], "main": "src/index.ts", "types": "src/index.ts", "files": [ @@ -38,7 +40,6 @@ "test": "backstage-cli package test" }, "dependencies": { - "@base-ui-components/react": "1.0.0-alpha.7", "@remixicon/react": "^4.6.0", "@tanstack/react-table": "^8.21.3", "clsx": "^2.1.1", diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md index 91d81e29e3..4f6087b0f0 100644 --- a/packages/ui/report.api.md +++ b/packages/ui/report.api.md @@ -3,15 +3,17 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { Avatar as Avatar_2 } from '@base-ui-components/react/avatar'; import { ButtonProps as ButtonProps_2 } from 'react-aria-components'; import { CellProps as CellProps_2 } from 'react-aria-components'; -import { Collapsible as Collapsible_2 } from '@base-ui-components/react/collapsible'; +import { CheckboxProps as CheckboxProps_2 } from 'react-aria-components'; import { ColumnProps as ColumnProps_2 } from 'react-aria-components'; import { ComponentProps } from 'react'; import type { ComponentPropsWithRef } from 'react'; import { DetailedHTMLProps } from 'react'; import type { DialogTriggerProps as DialogTriggerProps_2 } from 'react-aria-components'; +import type { DisclosureGroupProps } from 'react-aria-components'; +import type { DisclosurePanelProps } from 'react-aria-components'; +import type { DisclosureProps } from 'react-aria-components'; import type { ElementType } from 'react'; import { ForwardRefExoticComponent } from 'react'; import type { HeadingProps } from 'react-aria-components'; @@ -51,22 +53,70 @@ import type { TextFieldProps as TextFieldProps_2 } from 'react-aria-components'; import { TooltipProps as TooltipProps_2 } from 'react-aria-components'; import { TooltipTriggerComponentProps } from 'react-aria-components'; +// @public (undocumented) +export const Accordion: ForwardRefExoticComponent< + AccordionProps & RefAttributes +>; + +// @public (undocumented) +export const AccordionGroup: ForwardRefExoticComponent< + AccordionGroupProps & RefAttributes +>; + +// @public +export interface AccordionGroupProps extends DisclosureGroupProps { + allowsMultiple?: boolean; + // (undocumented) + className?: string; +} + +// @public (undocumented) +export const AccordionPanel: ForwardRefExoticComponent< + AccordionPanelProps & RefAttributes +>; + +// @public +export interface AccordionPanelProps extends DisclosurePanelProps { + // (undocumented) + className?: string; +} + +// @public +export interface AccordionProps extends DisclosureProps { + // (undocumented) + className?: string; +} + +// @public (undocumented) +export const AccordionTrigger: ForwardRefExoticComponent< + AccordionTriggerProps & RefAttributes +>; + +// @public +export interface AccordionTriggerProps extends HeadingProps { + // (undocumented) + children?: React.ReactNode; + // (undocumented) + className?: string; + // (undocumented) + subtitle?: string; + // (undocumented) + title?: string; +} + // @public (undocumented) export type AlignItems = 'stretch' | 'start' | 'center' | 'end'; // @public (undocumented) export const Avatar: ForwardRefExoticComponent< - AvatarProps & RefAttributes + AvatarProps & RefAttributes >; // @public (undocumented) -export interface AvatarProps - extends React.ComponentPropsWithoutRef { - // (undocumented) +export interface AvatarProps extends React.ComponentPropsWithoutRef<'div'> { name: string; - // (undocumented) - size?: 'small' | 'medium' | 'large'; - // (undocumented) + purpose?: 'decoration' | 'informative'; + size?: 'x-small' | 'small' | 'medium' | 'large' | 'x-large'; src: string; } @@ -137,6 +187,8 @@ export interface ButtonIconProps extends ButtonProps_2 { // (undocumented) icon?: ReactElement; // (undocumented) + loading?: boolean; + // (undocumented) size?: 'small' | 'medium' | Partial>; // (undocumented) variant?: @@ -178,6 +230,8 @@ export interface ButtonProps extends ButtonProps_2 { // (undocumented) iconStart?: ReactElement; // (undocumented) + loading?: boolean; + // (undocumented) size?: 'small' | 'medium' | Partial>; // (undocumented) variant?: @@ -270,55 +324,18 @@ export interface CellProps extends CellProps_2 { // @public (undocumented) export const Checkbox: ForwardRefExoticComponent< - CheckboxProps & RefAttributes + CheckboxProps & RefAttributes >; // @public (undocumented) -export interface CheckboxProps { +export interface CheckboxProps extends CheckboxProps_2 { // (undocumented) - checked?: boolean; - // (undocumented) - className?: string; - // (undocumented) - defaultChecked?: boolean; - // (undocumented) - disabled?: boolean; - // (undocumented) - label?: string; - // (undocumented) - name?: string; - // (undocumented) - onChange?: (checked: boolean) => void; - // (undocumented) - required?: boolean; - // (undocumented) - style?: React.CSSProperties; - // (undocumented) - value?: string; + children: React.ReactNode; } // @public export type ClassNamesMap = Record; -// @public -export const Collapsible: { - Root: ForwardRefExoticComponent< - Omit, 'ref'> & - RefAttributes - >; - Trigger: ForwardRefExoticComponent< - Omit< - Collapsible_2.Trigger.Props & RefAttributes, - 'ref' - > & - RefAttributes - >; - Panel: ForwardRefExoticComponent< - Omit, 'ref'> & - RefAttributes - >; -}; - // @public (undocumented) export const Column: (props: ColumnProps) => JSX_2.Element; @@ -405,15 +422,20 @@ export const componentDefinitions: { readonly Button: { readonly classNames: { readonly root: 'bui-Button'; + readonly content: 'bui-ButtonContent'; + readonly spinner: 'bui-ButtonSpinner'; }; readonly dataAttributes: { readonly size: readonly ['small', 'medium', 'large']; readonly variant: readonly ['primary', 'secondary', 'tertiary']; + readonly loading: readonly [true, false]; }; }; readonly ButtonIcon: { readonly classNames: { readonly root: 'bui-ButtonIcon'; + readonly content: 'bui-ButtonIconContent'; + readonly spinner: 'bui-ButtonIconSpinner'; }; }; readonly ButtonLink: { @@ -431,19 +453,11 @@ export const componentDefinitions: { }; readonly Checkbox: { readonly classNames: { - readonly root: 'bui-CheckboxRoot'; - readonly label: 'bui-CheckboxLabel'; + readonly root: 'bui-Checkbox'; readonly indicator: 'bui-CheckboxIndicator'; }; readonly dataAttributes: { - readonly checked: readonly [true, false]; - }; - }; - readonly Collapsible: { - readonly classNames: { - readonly root: 'bui-CollapsibleRoot'; - readonly trigger: 'bui-CollapsibleTrigger'; - readonly panel: 'bui-CollapsiblePanel'; + readonly selected: readonly [true, false]; }; }; readonly Container: { @@ -462,6 +476,18 @@ export const componentDefinitions: { readonly footer: 'bui-DialogFooter'; }; }; + readonly Accordion: { + readonly classNames: { + readonly root: 'bui-Accordion'; + readonly trigger: 'bui-AccordionTrigger'; + readonly triggerButton: 'bui-AccordionTriggerButton'; + readonly triggerTitle: 'bui-AccordionTriggerTitle'; + readonly triggerSubtitle: 'bui-AccordionTriggerSubtitle'; + readonly triggerIcon: 'bui-AccordionTriggerIcon'; + readonly panel: 'bui-AccordionPanel'; + readonly group: 'bui-AccordionGroup'; + }; + }; readonly FieldError: { readonly classNames: { readonly root: 'bui-FieldError'; @@ -571,6 +597,14 @@ export const componentDefinitions: { readonly dataAttributes: { readonly variant: readonly ['subtitle', 'body', 'caption', 'label']; readonly weight: readonly ['regular', 'bold']; + readonly color: readonly [ + 'primary', + 'secondary', + 'danger', + 'warning', + 'success', + ]; + readonly truncate: readonly [true, false]; }; }; readonly List: { @@ -603,7 +637,10 @@ export const componentDefinitions: { readonly PasswordField: { readonly classNames: { readonly root: 'bui-PasswordField'; - readonly inputVisibility: 'bui-InputVisibility'; + readonly inputWrapper: 'bui-PasswordFieldInputWrapper'; + readonly input: 'bui-PasswordFieldInput'; + readonly inputIcon: 'bui-PasswordFieldIcon'; + readonly inputVisibility: 'bui-PasswordFieldVisibility'; }; readonly dataAttributes: { readonly size: readonly ['small', 'medium']; @@ -624,7 +661,10 @@ export const componentDefinitions: { readonly SearchField: { readonly classNames: { readonly root: 'bui-SearchField'; - readonly clear: 'bui-InputClear'; + readonly clear: 'bui-SearchFieldClear'; + readonly inputWrapper: 'bui-SearchFieldInputWrapper'; + readonly input: 'bui-SearchFieldInput'; + readonly inputIcon: 'bui-SearchFieldInputIcon'; }; readonly dataAttributes: { readonly startCollapsed: readonly [true, false]; @@ -634,13 +674,18 @@ export const componentDefinitions: { readonly Select: { readonly classNames: { readonly root: 'bui-Select'; + readonly popover: 'bui-SelectPopover'; readonly trigger: 'bui-SelectTrigger'; + readonly chevron: 'bui-SelectTriggerChevron'; readonly value: 'bui-SelectValue'; - readonly icon: 'bui-SelectIcon'; readonly list: 'bui-SelectList'; readonly item: 'bui-SelectItem'; readonly itemIndicator: 'bui-SelectItemIndicator'; readonly itemLabel: 'bui-SelectItemLabel'; + readonly searchWrapper: 'bui-SelectSearchWrapper'; + readonly search: 'bui-SelectSearch'; + readonly searchClear: 'bui-SelectSearchClear'; + readonly noResults: 'bui-SelectNoResults'; }; readonly dataAttributes: { readonly size: readonly ['small', 'medium']; @@ -743,6 +788,11 @@ export const componentDefinitions: { readonly arrow: 'bui-TooltipArrow'; }; }; + readonly VisuallyHidden: { + readonly classNames: { + readonly root: 'bui-VisuallyHidden'; + }; + }; }; // @public (undocumented) @@ -845,7 +895,8 @@ export const FieldLabel: ForwardRefExoticComponent< >; // @public (undocumented) -export interface FieldLabelProps { +export interface FieldLabelProps + extends Pick, 'className'> { description?: string | null; htmlFor?: string; id?: string; @@ -941,6 +992,8 @@ export interface HeaderPageProps { // (undocumented) breadcrumbs?: HeaderPageBreadcrumb[]; // (undocumented) + className?: string; + // (undocumented) customActions?: React.ReactNode; // (undocumented) tabs?: HeaderTab[]; @@ -950,6 +1003,8 @@ export interface HeaderPageProps { // @public export interface HeaderProps { + // (undocumented) + className?: string; // (undocumented) customActions?: React.ReactNode; // (undocumented) @@ -1131,6 +1186,14 @@ export const MenuTrigger: (props: MenuTriggerProps) => JSX_2.Element; // @public (undocumented) export interface MenuTriggerProps extends MenuTriggerProps_2 {} +// @public (undocumented) +type Option_2 = { + value: string; + label: string; + disabled?: boolean; +}; +export { Option_2 as Option }; + // @public (undocumented) export const Radio: ForwardRefExoticComponent< RadioProps & RefAttributes @@ -1144,7 +1207,7 @@ export const RadioGroup: ForwardRefExoticComponent< // @public (undocumented) export interface RadioGroupProps extends Omit, - Omit { + Omit { // (undocumented) children?: ReactNode; } @@ -1166,7 +1229,7 @@ export const SearchField: ForwardRefExoticComponent< // @public (undocumented) export interface SearchFieldProps extends SearchFieldProps_2, - Omit { + Omit { icon?: ReactNode | false; placeholder?: string; size?: 'small' | 'medium' | Partial>; @@ -1175,22 +1238,18 @@ export interface SearchFieldProps // @public (undocumented) export const Select: ForwardRefExoticComponent< - SelectProps & RefAttributes + SelectProps<'multiple' | 'single'> & RefAttributes >; // @public (undocumented) -export interface SelectProps - extends SelectProps_2<{ - name: string; - value: string; - }>, - Omit { +export interface SelectProps + extends SelectProps_2, + Omit { icon?: ReactNode; - options?: Array<{ - value: string; - label: string; - disabled?: boolean; - }>; + options?: Array; + searchable?: boolean; + searchPlaceholder?: string; + selectionMode?: T; size?: 'small' | 'medium' | Partial>; } @@ -1387,7 +1446,7 @@ export const TextField: ForwardRefExoticComponent< // @public (undocumented) export interface TextFieldProps extends TextFieldProps_2, - Omit { + Omit { icon?: ReactNode; placeholder?: string; size?: 'small' | 'medium' | Partial>; @@ -1534,4 +1593,13 @@ export interface UtilityProps extends SpaceProps { // (undocumented) rowSpan?: Responsive; } + +// @public +export const VisuallyHidden: (props: VisuallyHiddenProps) => JSX_2.Element; + +// @public +export interface VisuallyHiddenProps extends ComponentProps<'div'> { + // (undocumented) + children?: React.ReactNode; +} ``` diff --git a/packages/ui/src/components/Accordion/Accordion.module.css b/packages/ui/src/components/Accordion/Accordion.module.css new file mode 100644 index 0000000000..a86400986d --- /dev/null +++ b/packages/ui/src/components/Accordion/Accordion.module.css @@ -0,0 +1,93 @@ +/* + * Copyright 2025 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. + */ + +@layer tokens, base, components, utilities; + +@layer components { + .bui-Accordion { + width: 100%; + background-color: var(--bui-bg-surface-1); + border-radius: var(--bui-radius-3); + padding: var(--bui-space-3); + } + + .bui-AccordionTrigger { + all: unset; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + } + + .bui-AccordionTriggerButton { + all: unset; + width: 100%; + color: var(--bui-fg-primary); + display: flex; + align-items: center; + justify-content: space-between; + cursor: pointer; + text-align: left; + + &:focus-visible { + outline: none; + transition: none; + box-shadow: inset 0 0 0 2px var(--bui-ring); + } + + &[data-disabled='true'] { + background-color: transparent; + color: var(--bui-fg-disabled); + cursor: not-allowed; + } + } + + .bui-AccordionTriggerTitle { + font-size: var(--bui-font-size-4); + font-weight: var(--bui-font-weight-bold); + line-height: 140%; + } + + .bui-AccordionTriggerSubtitle { + font-size: var(--bui-font-size-2); + line-height: 140%; + color: var(--bui-fg-secondary); + } + + .bui-AccordionTriggerIcon { + transition: transform 150ms ease-out; + flex-shrink: 0; + width: 1rem; + height: 1rem; + + [data-expanded='true'] & { + transform: rotate(180deg); + } + } + + .bui-AccordionPanel { + [data-expanded='true'] & { + padding-top: var(--bui-space-1); + } + } + + .bui-AccordionGroup { + display: flex; + flex-direction: column; + gap: var(--bui-space-3); + width: 100%; + } +} diff --git a/packages/ui/src/components/Accordion/Accordion.stories.tsx b/packages/ui/src/components/Accordion/Accordion.stories.tsx new file mode 100644 index 0000000000..6640bd5d6a --- /dev/null +++ b/packages/ui/src/components/Accordion/Accordion.stories.tsx @@ -0,0 +1,177 @@ +/* + * Copyright 2025 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 type { Meta, StoryObj } from '@storybook/react-vite'; +import { + Accordion, + AccordionTrigger, + AccordionPanel, + AccordionGroup, +} from './Accordion'; +import { Box } from '../Box'; +import { Text } from '../Text'; + +const Content = () => ( + + + It's the edge of the world and all of Western civilization + + + The sun may rise in the East, at least it settled in a final location + + It's understood that Hollywood sells Californication + +); + +const meta = { + title: 'Backstage UI/Accordion', + component: Accordion, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => ( + + + + + + + ), +}; + +export const WithSubtitle: Story = { + render: () => ( + + + + + + + ), +}; + +export const CustomTrigger: Story = { + render: () => ( + + + + + Custom Multi-line Trigger + + + Click to expand additional details and configuration options + + + + + + + + ), +}; + +export const DefaultExpanded: Story = { + render: () => ( + + + + + + + ), +}; + +export const GroupSingleOpen: Story = { + render: () => ( + + + + + + + It's the edge of the world and all of Western civilization + + + + + + + + + + The sun may rise in the East, at least it settled in a final + location + + + + + + + + + + It's understood that Hollywood sells Californication + + + + + + ), +}; + +export const GroupMultipleOpen: Story = { + render: () => ( + + + + + + + It's the edge of the world and all of Western civilization + + + + + + + + + + The sun may rise in the East, at least it settled in a final + location + + + + + + + + + + It's understood that Hollywood sells Californication + + + + + + ), +}; diff --git a/packages/ui/src/components/Accordion/Accordion.tsx b/packages/ui/src/components/Accordion/Accordion.tsx new file mode 100644 index 0000000000..3f35ab7554 --- /dev/null +++ b/packages/ui/src/components/Accordion/Accordion.tsx @@ -0,0 +1,153 @@ +/* + * Copyright 2025 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 { forwardRef } from 'react'; +import { + Disclosure as RADisclosure, + Button as RAButton, + DisclosurePanel as RADisclosurePanel, + DisclosureGroup as RADisclosureGroup, + Heading as RAHeading, +} from 'react-aria-components'; +import { RiArrowDownSLine } from '@remixicon/react'; +import clsx from 'clsx'; +import type { + AccordionProps, + AccordionTriggerProps, + AccordionPanelProps, + AccordionGroupProps, +} from './types'; +import { useStyles } from '../../hooks/useStyles'; +import styles from './Accordion.module.css'; +import { Flex } from '../Flex'; + +/** @public */ +export const Accordion = forwardRef< + React.ElementRef, + AccordionProps +>(({ className, ...props }, ref) => { + const { classNames, cleanedProps } = useStyles('Accordion', props); + + return ( + + ); +}); + +Accordion.displayName = 'Accordion'; + +/** @public */ +export const AccordionTrigger = forwardRef< + React.ElementRef, + AccordionTriggerProps +>(({ className, title, subtitle, children, ...props }, ref) => { + const { classNames, cleanedProps } = useStyles('Accordion', props); + + return ( + + + {children ? ( + children + ) : ( + + + {title} + + {subtitle && ( + + {subtitle} + + )} + + )} + + + + + ); +}); + +AccordionTrigger.displayName = 'AccordionTrigger'; + +/** @public */ +export const AccordionPanel = forwardRef< + React.ElementRef, + AccordionPanelProps +>(({ className, ...props }, ref) => { + const { classNames, cleanedProps } = useStyles('Accordion', props); + + return ( + + ); +}); + +AccordionPanel.displayName = 'AccordionPanel'; + +/** @public */ +export const AccordionGroup = forwardRef< + React.ElementRef, + AccordionGroupProps +>(({ className, allowsMultiple = false, ...props }, ref) => { + const { classNames, cleanedProps } = useStyles('Accordion', props); + + return ( + + ); +}); + +AccordionGroup.displayName = 'AccordionGroup'; diff --git a/packages/ui/src/components/Accordion/index.ts b/packages/ui/src/components/Accordion/index.ts new file mode 100644 index 0000000000..cd34b4bc87 --- /dev/null +++ b/packages/ui/src/components/Accordion/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2025 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 { + Accordion, + AccordionTrigger, + AccordionPanel, + AccordionGroup, +} from './Accordion'; +export type { + AccordionProps, + AccordionTriggerProps, + AccordionPanelProps, + AccordionGroupProps, +} from './types'; diff --git a/packages/ui/src/components/Accordion/types.ts b/packages/ui/src/components/Accordion/types.ts new file mode 100644 index 0000000000..06c8549ebd --- /dev/null +++ b/packages/ui/src/components/Accordion/types.ts @@ -0,0 +1,62 @@ +/* + * Copyright 2025 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 type { + DisclosureProps as RADisclosureProps, + HeadingProps as RAHeadingProps, + DisclosurePanelProps as RADisclosurePanelProps, + DisclosureGroupProps as RADisclosureGroupProps, +} from 'react-aria-components'; + +/** + * Props for the Accordion component. + * @public + */ +export interface AccordionProps extends RADisclosureProps { + className?: string; +} + +/** + * Props for the AccordionTrigger component. + * @public + */ +export interface AccordionTriggerProps extends RAHeadingProps { + className?: string; + title?: string; + subtitle?: string; + children?: React.ReactNode; +} + +/** + * Props for the AccordionPanel component. + * @public + */ +export interface AccordionPanelProps extends RADisclosurePanelProps { + className?: string; +} + +/** + * Props for the AccordionGroup component. + * @public + */ +export interface AccordionGroupProps extends RADisclosureGroupProps { + className?: string; + /** + * Whether multiple accordions can be expanded at the same time. + * @defaultValue false + */ + allowsMultiple?: boolean; +} diff --git a/packages/ui/src/components/Avatar/Avatar.module.css b/packages/ui/src/components/Avatar/Avatar.module.css index f1517db3c2..c1fec3df9b 100644 --- a/packages/ui/src/components/Avatar/Avatar.module.css +++ b/packages/ui/src/components/Avatar/Avatar.module.css @@ -34,6 +34,11 @@ width: 2rem; } + .bui-AvatarRoot[data-size='x-small'] { + height: 1.25rem; + width: 1.25rem; + } + .bui-AvatarRoot[data-size='small'] { height: 1.5rem; width: 1.5rem; @@ -45,6 +50,11 @@ } .bui-AvatarRoot[data-size='large'] { + height: 2.5rem; + width: 2.5rem; + } + + .bui-AvatarRoot[data-size='x-large'] { height: 3rem; width: 3rem; } @@ -53,6 +63,7 @@ object-fit: cover; height: 100%; width: 100%; + display: block; } .bui-AvatarFallback { diff --git a/packages/ui/src/components/Avatar/Avatar.stories.tsx b/packages/ui/src/components/Avatar/Avatar.stories.tsx index c91fe736db..582d82393e 100644 --- a/packages/ui/src/components/Avatar/Avatar.stories.tsx +++ b/packages/ui/src/components/Avatar/Avatar.stories.tsx @@ -16,7 +16,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { Avatar } from './index'; -import { Flex } from '../..'; +import { Flex, Text } from '../..'; const meta = { title: 'Backstage UI/Avatar', @@ -45,10 +45,52 @@ export const Sizes: Story = { ...Default.args, }, render: args => ( - - - - + + + + + + + + + + + + + + + + + ), +}; + +export const Purpose: Story = { + args: { + ...Default.args, + }, + render: args => ( + + + Informative (default) + + Use when avatar appears alone. Announced as "{args.name}" to screen + readers: + + + + + + + Decoration + + Use when name appears adjacent to avatar. Hidden from screen readers + to avoid redundancy: + + + + {args.name} + + ), }; diff --git a/packages/ui/src/components/Avatar/Avatar.tsx b/packages/ui/src/components/Avatar/Avatar.tsx index 000087d451..7cbb4f80c7 100644 --- a/packages/ui/src/components/Avatar/Avatar.tsx +++ b/packages/ui/src/components/Avatar/Avatar.tsx @@ -14,48 +14,76 @@ * limitations under the License. */ -import { forwardRef, ElementRef } from 'react'; -import { Avatar as AvatarPrimitive } from '@base-ui-components/react/avatar'; +import { forwardRef, useState, useEffect } from 'react'; import clsx from 'clsx'; import { AvatarProps } from './types'; import { useStyles } from '../../hooks/useStyles'; import styles from './Avatar.module.css'; /** @public */ -export const Avatar = forwardRef< - ElementRef, - AvatarProps ->((props, ref) => { +export const Avatar = forwardRef((props, ref) => { const { classNames, dataAttributes, cleanedProps } = useStyles('Avatar', { size: 'medium', + purpose: 'informative', ...props, }); - const { className, src, name, ...rest } = cleanedProps; + const { className, src, name, purpose, ...rest } = cleanedProps; + + const [imageStatus, setImageStatus] = useState< + 'loading' | 'loaded' | 'error' + >('loading'); + + useEffect(() => { + setImageStatus('loading'); + const img = new Image(); + img.onload = () => setImageStatus('loaded'); + img.onerror = () => setImageStatus('error'); + img.src = src; + + return () => { + img.onload = null; + img.onerror = null; + }; + }, [src]); + + const initialsCount = ['x-small', 'small'].includes(cleanedProps.size) + ? 1 + : 2; + + const initials = name + .split(' ') + .map(word => word[0]) + .join('') + .toLocaleUpperCase('en-US') + .slice(0, initialsCount); return ( - - - - {(name || '') - .split(' ') - .map(word => word[0]) - .join('') - .toLocaleUpperCase('en-US') - .slice(0, 2)} - - + {imageStatus === 'loaded' ? ( + + ) : ( + + )} +
  • ); }); -Avatar.displayName = AvatarPrimitive.Root.displayName; +Avatar.displayName = 'Avatar'; diff --git a/packages/ui/src/components/Avatar/types.ts b/packages/ui/src/components/Avatar/types.ts index b2e6cf39cf..a252861ea4 100644 --- a/packages/ui/src/components/Avatar/types.ts +++ b/packages/ui/src/components/Avatar/types.ts @@ -14,12 +14,29 @@ * limitations under the License. */ -import { Avatar } from '@base-ui-components/react/avatar'; - /** @public */ -export interface AvatarProps - extends React.ComponentPropsWithoutRef { +export interface AvatarProps extends React.ComponentPropsWithoutRef<'div'> { + /** + * URL of the image to display + */ src: string; + + /** + * Name of the person - used for generating initials and accessibility labels + */ name: string; - size?: 'small' | 'medium' | 'large'; + + /** + * Size of the avatar + * @defaultValue 'medium' + */ + size?: 'x-small' | 'small' | 'medium' | 'large' | 'x-large'; + + /** + * Determines how the avatar is presented to assistive technologies. + * - 'informative': Avatar is announced as "\{name\}" to screen readers + * - 'decoration': Avatar is hidden from screen readers (use when name appears in adjacent text) + * @defaultValue 'informative' + */ + purpose?: 'decoration' | 'informative'; } diff --git a/packages/ui/src/components/Button/Button.module.css b/packages/ui/src/components/Button/Button.module.css index 2216d0882b..a87f5d67cf 100644 --- a/packages/ui/src/components/Button/Button.module.css +++ b/packages/ui/src/components/Button/Button.module.css @@ -18,22 +18,27 @@ @layer components { .bui-Button { - border: none; + --loading-duration: 200ms; + position: relative; display: inline-flex; - align-items: center; - justify-content: center; + border: none; user-select: none; font-family: var(--bui-font-regular); font-weight: var(--bui-font-weight-bold); padding: 0; cursor: pointer; border-radius: var(--bui-radius-2); - gap: var(--bui-space-1_5); flex-shrink: 0; + transition: background-color var(--loading-duration) ease-out, + box-shadow var(--loading-duration) ease-out; &[data-disabled='true'] { cursor: not-allowed; } + + &[data-loading='true'] { + cursor: wait; + } } .bui-Button[data-variant='primary'] { @@ -54,7 +59,8 @@ outline-offset: 2px; } - &[data-disabled='true'] { + &[data-disabled='true'], + &[data-loading='true'] { background-color: var(--bui-bg-solid-disabled); color: var(--bui-fg-solid-disabled); } @@ -80,7 +86,8 @@ box-shadow: inset 0 0 0 2px var(--bui-ring); } - &[data-disabled='true'] { + &[data-disabled='true'], + &[data-loading='true'] { box-shadow: inset 0 0 0 1px var(--bui-border-disabled); color: var(--bui-fg-disabled); } @@ -105,31 +112,92 @@ box-shadow: inset 0 0 0 2px var(--bui-ring); } - &[data-disabled='true'] { + &[data-disabled='true'], + &[data-loading='true'] { background-color: transparent; color: var(--bui-fg-disabled); } } + .bui-Button[data-size='small'] { + font-size: var(--bui-font-size-3); + padding: 0 var(--bui-space-2); + height: 2rem; + + svg { + width: 1rem; + height: 1rem; + } + } + .bui-Button[data-size='medium'] { font-size: var(--bui-font-size-4); padding: 0 var(--bui-space-3); height: 2.5rem; + + svg { + width: 1.25rem; + height: 1.25rem; + } } - .bui-Button[data-size='small'] { - font-size: var(--bui-font-size-3); - padding: 0 var(--bui-space-2); - height: 2rem; + .bui-ButtonContent { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--bui-space-1_5); + height: 100%; + width: 100%; + transition: opacity var(--loading-duration) ease-out; + + .bui-Button[data-loading='true'] & { + opacity: 0; + } } - .bui-Button[data-size='small'] svg { - width: 1rem; - height: 1rem; + .bui-ButtonSpinner { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: flex; + opacity: 0; + transition: opacity var(--loading-duration) ease-in; + + .bui-Button[data-loading='true'] & { + opacity: 1; + } + + & svg { + animation: bui-spin 1s linear infinite; + } } - .bui-Button[data-size='medium'] svg { - width: 1.25rem; - height: 1.25rem; + @media (prefers-reduced-motion: reduce) { + .bui-Button { + transition-duration: 50ms; + } + + .bui-ButtonContent { + transition-duration: 50ms; + } + + .bui-ButtonSpinner { + transition-duration: 50ms; + } + + .bui-ButtonSpinner svg { + animation: none; + } + } + + @keyframes bui-spin { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } } } diff --git a/packages/ui/src/components/Button/Button.stories.tsx b/packages/ui/src/components/Button/Button.stories.tsx index 6b74615eeb..4734770aa4 100644 --- a/packages/ui/src/components/Button/Button.stories.tsx +++ b/packages/ui/src/components/Button/Button.stories.tsx @@ -19,6 +19,7 @@ import { Button } from './Button'; import { Flex } from '../Flex'; import { Text } from '../Text'; import { RiArrowRightSLine, RiCloudLine } from '@remixicon/react'; +import { useState } from 'react'; const meta = { title: 'Backstage UI/Button', @@ -212,3 +213,80 @@ export const Playground: Story = { ), }; + +export const Loading: Story = { + render: () => { + const [isLoading, setIsLoading] = useState(false); + + const handleClick = () => { + setIsLoading(true); + setTimeout(() => { + setIsLoading(false); + }, 3000); + }; + + return ( + + ); + }, +}; + +export const LoadingVariants: Story = { + render: () => ( + + Primary + + + + + + + Secondary + + + + + + + Tertiary + + + + + + + Loading vs Disabled + + + + + + + ), +}; diff --git a/packages/ui/src/components/Button/Button.tsx b/packages/ui/src/components/Button/Button.tsx index d22a3036e6..45228ff6ef 100644 --- a/packages/ui/src/components/Button/Button.tsx +++ b/packages/ui/src/components/Button/Button.tsx @@ -16,7 +16,8 @@ import clsx from 'clsx'; import { forwardRef, Ref } from 'react'; -import { Button as RAButton } from 'react-aria-components'; +import { Button as RAButton, ProgressBar } from 'react-aria-components'; +import { RiLoader4Line } from '@remixicon/react'; import type { ButtonProps } from './types'; import { useStyles } from '../../hooks/useStyles'; import styles from './Button.module.css'; @@ -30,18 +31,38 @@ export const Button = forwardRef( ...props, }); - const { children, className, iconStart, iconEnd, ...rest } = cleanedProps; + const { children, className, iconStart, iconEnd, loading, ...rest } = + cleanedProps; return ( - {iconStart} - {children} - {iconEnd} + {({ isPending }) => ( + <> + + {iconStart} + {children} + {iconEnd} + + + {isPending && ( + + + )} + + )} ); }, diff --git a/packages/ui/src/components/Button/types.ts b/packages/ui/src/components/Button/types.ts index cbe5bd3608..daeba7653f 100644 --- a/packages/ui/src/components/Button/types.ts +++ b/packages/ui/src/components/Button/types.ts @@ -33,4 +33,5 @@ export interface ButtonProps extends RAButtonProps { iconStart?: ReactElement; iconEnd?: ReactElement; children?: ReactNode; + loading?: boolean; } diff --git a/packages/ui/src/components/ButtonIcon/ButtonIcon.stories.tsx b/packages/ui/src/components/ButtonIcon/ButtonIcon.stories.tsx index c1a908119f..97072c3664 100644 --- a/packages/ui/src/components/ButtonIcon/ButtonIcon.stories.tsx +++ b/packages/ui/src/components/ButtonIcon/ButtonIcon.stories.tsx @@ -17,7 +17,9 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { ButtonIcon } from './ButtonIcon'; import { Flex } from '../Flex'; +import { Text } from '../Text'; import { RiCloudLine } from '@remixicon/react'; +import { useState } from 'react'; const meta = { title: 'Backstage UI/ButtonIcon', @@ -83,3 +85,91 @@ export const Responsive: Story = { }, render: args => } />, }; + +export const Loading: Story = { + render: () => { + const [isLoading, setIsLoading] = useState(false); + + const handleClick = () => { + setIsLoading(true); + setTimeout(() => { + setIsLoading(false); + }, 3000); + }; + + return ( + } + loading={isLoading} + onPress={handleClick} + /> + ); + }, +}; + +export const LoadingVariants: Story = { + render: () => ( + + Primary + + } + loading + /> + } + loading + /> + + + Secondary + + } + loading + /> + } + loading + /> + + + Tertiary + + } + loading + /> + } + loading + /> + + + Loading vs Disabled + + } loading /> + } isDisabled /> + } + loading + isDisabled + /> + + + ), +}; diff --git a/packages/ui/src/components/ButtonIcon/ButtonIcon.tsx b/packages/ui/src/components/ButtonIcon/ButtonIcon.tsx index 2e6a96c4c1..fecccd6a37 100644 --- a/packages/ui/src/components/ButtonIcon/ButtonIcon.tsx +++ b/packages/ui/src/components/ButtonIcon/ButtonIcon.tsx @@ -16,7 +16,8 @@ import clsx from 'clsx'; import { forwardRef, Ref } from 'react'; -import { Button as RAButton } from 'react-aria-components'; +import { Button as RAButton, ProgressBar } from 'react-aria-components'; +import { RiLoader4Line } from '@remixicon/react'; import type { ButtonIconProps } from './types'; import { useStyles } from '../../hooks/useStyles'; import stylesButtonIcon from './ButtonIcon.module.css'; @@ -33,7 +34,7 @@ export const ButtonIcon = forwardRef( const { classNames: classNamesButtonIcon } = useStyles('ButtonIcon'); - const { className, icon, ...rest } = cleanedProps; + const { className, icon, loading, ...rest } = cleanedProps; return ( - {icon} + {({ isPending }) => ( + <> + + {icon} + + + {isPending && ( + + + )} + + )} ); }, diff --git a/packages/ui/src/components/ButtonIcon/types.ts b/packages/ui/src/components/ButtonIcon/types.ts index bc358b6d7d..6af3d12361 100644 --- a/packages/ui/src/components/ButtonIcon/types.ts +++ b/packages/ui/src/components/ButtonIcon/types.ts @@ -31,4 +31,5 @@ export interface ButtonIconProps extends RAButtonProps { | 'tertiary' | Partial>; icon?: ReactElement; + loading?: boolean; } diff --git a/packages/ui/src/components/ButtonLink/ButtonLink.tsx b/packages/ui/src/components/ButtonLink/ButtonLink.tsx index 70d216b3d8..28a67105bb 100644 --- a/packages/ui/src/components/ButtonLink/ButtonLink.tsx +++ b/packages/ui/src/components/ButtonLink/ButtonLink.tsx @@ -41,47 +41,38 @@ export const ButtonLink = forwardRef( const isExternal = isExternalLink(href); - // If it's an external link, render RALink without RouterProvider - if (isExternal) { - return ( - + {iconStart} {children} {iconEnd} - - ); + + + ); + + // If it's an external link, render RALink without RouterProvider + if (isExternal) { + return linkButton; } // For internal links, use RouterProvider return ( - - {iconStart} - {children} - {iconEnd} - + {linkButton} ); }, diff --git a/packages/ui/src/components/Checkbox/Checkbox.module.css b/packages/ui/src/components/Checkbox/Checkbox.module.css index 2e08b08c1a..bc4f700bce 100644 --- a/packages/ui/src/components/Checkbox/Checkbox.module.css +++ b/packages/ui/src/components/Checkbox/Checkbox.module.css @@ -17,35 +17,7 @@ @layer tokens, base, components, utilities; @layer components { - .bui-CheckboxRoot { - border: none; - display: flex; - align-items: center; - justify-content: center; - width: 1rem; - height: 1rem; - box-shadow: inset 0 0 0 1px var(--bui-border); - cursor: pointer; - border-radius: 2px; - transition: background-color 0.2s ease-in-out; - background-color: var(--bui-bg-surface-1); - padding: 0; - flex-shrink: 0; - } - - .bui-CheckboxRoot:focus-visible { - transition: none; - outline: 2px solid var(--bui-ring); - outline-offset: 2px; - } - - .bui-CheckboxRoot[data-checked] { - background-color: var(--bui-bg-solid); - box-shadow: none; - color: var(--bui-fg-solid); - } - - .bui-CheckboxLabel { + .bui-Checkbox { display: flex; flex-direction: row; align-items: center; @@ -55,18 +27,48 @@ font-weight: var(--bui-font-weight-regular); color: var(--bui-fg-primary); user-select: none; + cursor: pointer; + } - &:hover { - & .bui-CheckboxRoot:not([data-checked]) { - box-shadow: inset 0 0 0 1px var(--bui-border-hover); + .bui-Checkbox[data-disabled] { + cursor: not-allowed; + opacity: 0.5; + } + + .bui-CheckboxIndicator { + border: none; + display: flex; + align-items: center; + justify-content: center; + width: 1rem; + height: 1rem; + box-shadow: inset 0 0 0 1px var(--bui-border); + border-radius: 2px; + transition: background-color 0.2s ease-in-out; + background-color: var(--bui-bg-surface-1); + padding: 0; + flex-shrink: 0; + color: var(--bui-fg-solid); + + @media (prefers-reduced-motion: reduce) { + & { + transition: none; } } } - .bui-CheckboxIndicator { - display: flex; - align-items: center; - justify-content: center; - color: var(--bui-fg-solid); + .bui-Checkbox[data-focus-visible] .bui-CheckboxIndicator { + transition: none; + outline: 2px solid var(--bui-ring); + outline-offset: 2px; + } + + .bui-Checkbox[data-selected] .bui-CheckboxIndicator { + background-color: var(--bui-bg-solid); + box-shadow: none; + } + + .bui-Checkbox[data-hovered]:not([data-selected]) .bui-CheckboxIndicator { + box-shadow: inset 0 0 0 1px var(--bui-border-hover); } } diff --git a/packages/ui/src/components/Checkbox/Checkbox.stories.tsx b/packages/ui/src/components/Checkbox/Checkbox.stories.tsx index 080cae40b6..a41b7f2c8d 100644 --- a/packages/ui/src/components/Checkbox/Checkbox.stories.tsx +++ b/packages/ui/src/components/Checkbox/Checkbox.stories.tsx @@ -17,7 +17,6 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { Checkbox } from './Checkbox'; import { Flex } from '../Flex'; -import { Text } from '../Text'; const meta = { title: 'Backstage UI/Checkbox', @@ -29,31 +28,20 @@ type Story = StoryObj; export const Default: Story = { args: { - label: 'Accept terms and conditions', + children: 'Accept terms and conditions', }, }; export const AllVariants: Story = { + ...Default, render: () => ( - - - - - - - ), -}; - -export const Playground: Story = { - render: () => ( - - All variants - - - - - - + + Unchecked + Checked + Disabled + + Checked & Disabled + ), }; diff --git a/packages/ui/src/components/Checkbox/Checkbox.tsx b/packages/ui/src/components/Checkbox/Checkbox.tsx index 2414f29f5f..49019370a4 100644 --- a/packages/ui/src/components/Checkbox/Checkbox.tsx +++ b/packages/ui/src/components/Checkbox/Checkbox.tsx @@ -15,7 +15,7 @@ */ import { forwardRef } from 'react'; -import { Checkbox as CheckboxPrimitive } from '@base-ui-components/react/checkbox'; +import { Checkbox as RACheckbox } from 'react-aria-components'; import type { CheckboxProps } from './types'; import { useStyles } from '../../hooks/useStyles'; import clsx from 'clsx'; @@ -23,33 +23,24 @@ import styles from './Checkbox.module.css'; import { RiCheckLine } from '@remixicon/react'; /** @public */ -export const Checkbox = forwardRef( +export const Checkbox = forwardRef( (props, ref) => { - const { classNames, cleanedProps } = useStyles('Checkbox', props); - const { label, onChange, className, ...rest } = cleanedProps; + const { classNames } = useStyles('Checkbox'); + const { className, children, ...rest } = props; - const checkboxElement = ( - - - - - ); - - return label ? ( - - ) : ( - checkboxElement +
    + {children} + ); }, ); diff --git a/packages/ui/src/components/Checkbox/types.ts b/packages/ui/src/components/Checkbox/types.ts index 0240954afa..86e4b620b8 100644 --- a/packages/ui/src/components/Checkbox/types.ts +++ b/packages/ui/src/components/Checkbox/types.ts @@ -13,17 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { CheckboxProps as RACheckboxProps } from 'react-aria-components'; /** @public */ -export interface CheckboxProps { - label?: string; - defaultChecked?: boolean; - checked?: boolean; - onChange?: (checked: boolean) => void; - disabled?: boolean; - required?: boolean; - className?: string; - name?: string; - value?: string; - style?: React.CSSProperties; +export interface CheckboxProps extends RACheckboxProps { + children: React.ReactNode; } diff --git a/packages/ui/src/components/Collapsible/Collapsible.stories.tsx b/packages/ui/src/components/Collapsible/Collapsible.stories.tsx deleted file mode 100644 index 47b76f2f56..0000000000 --- a/packages/ui/src/components/Collapsible/Collapsible.stories.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2025 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 type { Meta, StoryObj } from '@storybook/react-vite'; -import { Collapsible } from './Collapsible'; -import { Button } from '../Button'; -import { Box } from '../Box'; -import { Text } from '../Text'; -import { RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/react'; - -const meta = { - title: 'Backstage UI/Collapsible', - component: Collapsible.Root, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - style: { - display: 'flex', - flexDirection: 'column', - gap: 'var(--bui-space-2)', - alignItems: 'center', - }, - children: ( - <> - ( - - )} - /> - - - - It's the edge of the world and all of Western civilization - - - The sun may rise in the East, at least it settled in a final - location - - It's understood that Hollywood sells Californication - - - - ), - }, -}; - -export const Open: Story = { - args: { - ...Default.args, - defaultOpen: true, - }, -}; diff --git a/packages/ui/src/components/Collapsible/Collapsible.tsx b/packages/ui/src/components/Collapsible/Collapsible.tsx deleted file mode 100644 index c9417d2019..0000000000 --- a/packages/ui/src/components/Collapsible/Collapsible.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2025 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 { forwardRef } from 'react'; -import { Collapsible as CollapsiblePrimitive } from '@base-ui-components/react/collapsible'; -import clsx from 'clsx'; -import { useStyles } from '../../hooks/useStyles'; -import styles from './Collapsible.module.css'; - -const CollapsibleRoot = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { - const { classNames, cleanedProps } = useStyles('Collapsible', props); - - return ( - - ); -}); -CollapsibleRoot.displayName = CollapsiblePrimitive.Root.displayName; - -const CollapsibleTrigger = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { - const { classNames, cleanedProps } = useStyles('Collapsible', props); - - return ( - - ); -}); -CollapsibleTrigger.displayName = CollapsiblePrimitive.Trigger.displayName; - -const CollapsiblePanel = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { - const { classNames, cleanedProps } = useStyles('Collapsible', props); - - return ( - - ); -}); -CollapsiblePanel.displayName = CollapsiblePrimitive.Panel.displayName; - -/** - * Collapsible is a component that allows you to collapse and expand content. - * It is a wrapper around the CollapsiblePrimitive component from base-ui-components. - * - * @public - */ -export const Collapsible = { - Root: CollapsibleRoot, - Trigger: CollapsibleTrigger, - Panel: CollapsiblePanel, -}; diff --git a/packages/ui/src/components/Dialog/Dialog.module.css b/packages/ui/src/components/Dialog/Dialog.module.css index 22d96146ea..5101cbf67c 100644 --- a/packages/ui/src/components/Dialog/Dialog.module.css +++ b/packages/ui/src/components/Dialog/Dialog.module.css @@ -23,7 +23,7 @@ left: 0; width: 100%; height: 100%; - background: rgba(232, 232, 232, 0.8); + background: color-mix(in srgb, var(--bui-gray-2) 80%, transparent); display: flex; align-items: center; justify-content: center; diff --git a/packages/ui/src/components/FieldLabel/FieldLabel.tsx b/packages/ui/src/components/FieldLabel/FieldLabel.tsx index 475b053344..5b27dd876f 100644 --- a/packages/ui/src/components/FieldLabel/FieldLabel.tsx +++ b/packages/ui/src/components/FieldLabel/FieldLabel.tsx @@ -24,14 +24,21 @@ import clsx from 'clsx'; export const FieldLabel = forwardRef( (props: FieldLabelProps, ref) => { const { classNames, cleanedProps } = useStyles('FieldLabel', props); - const { label, secondaryLabel, description, htmlFor, id, ...rest } = - cleanedProps; + const { + className, + label, + secondaryLabel, + description, + htmlFor, + id, + ...rest + } = cleanedProps; if (!label) return null; return (
    diff --git a/packages/ui/src/components/FieldLabel/types.ts b/packages/ui/src/components/FieldLabel/types.ts index dc4e444133..7f1d8a24b1 100644 --- a/packages/ui/src/components/FieldLabel/types.ts +++ b/packages/ui/src/components/FieldLabel/types.ts @@ -15,7 +15,8 @@ */ /** @public */ -export interface FieldLabelProps { +export interface FieldLabelProps + extends Pick, 'className'> { /** * The label of the text field */ diff --git a/packages/ui/src/components/Header/Header.tsx b/packages/ui/src/components/Header/Header.tsx index ad5c704a3a..6f42820be4 100644 --- a/packages/ui/src/components/Header/Header.tsx +++ b/packages/ui/src/components/Header/Header.tsx @@ -35,8 +35,15 @@ declare module 'react-aria-components' { */ export const Header = (props: HeaderProps) => { const { classNames, cleanedProps } = useStyles('Header', props); - const { tabs, icon, title, titleLink, customActions, onTabSelectionChange } = - cleanedProps; + const { + className, + tabs, + icon, + title, + titleLink, + customActions, + onTabSelectionChange, + } = cleanedProps; const hasTabs = tabs && tabs.length > 0; @@ -54,6 +61,7 @@ export const Header = (props: HeaderProps) => { className={clsx( classNames.tabsWrapper, styles[classNames.tabsWrapper], + className, )} > diff --git a/packages/ui/src/components/Header/HeaderToolbar.tsx b/packages/ui/src/components/Header/HeaderToolbar.tsx index 343922ff02..373f3462be 100644 --- a/packages/ui/src/components/Header/HeaderToolbar.tsx +++ b/packages/ui/src/components/Header/HeaderToolbar.tsx @@ -14,13 +14,12 @@ * limitations under the License. */ -import { Link, RouterProvider } from 'react-aria-components'; +import { Link } from 'react-aria-components'; import { useStyles } from '../../hooks/useStyles'; import { useRef } from 'react'; import { RiShapesLine } from '@remixicon/react'; import type { HeaderToolbarProps } from './types'; import { Text } from '../Text'; -import { useNavigate, useHref } from 'react-router-dom'; import styles from './Header.module.css'; import clsx from 'clsx'; @@ -31,8 +30,8 @@ import clsx from 'clsx'; */ export const HeaderToolbar = (props: HeaderToolbarProps) => { const { classNames, cleanedProps } = useStyles('Header', props); - const { icon, title, titleLink, customActions, hasTabs } = cleanedProps; - let navigate = useNavigate(); + const { className, icon, title, titleLink, customActions, hasTabs } = + cleanedProps; // Refs for collision detection const toolbarWrapperRef = useRef(null); @@ -51,59 +50,61 @@ export const HeaderToolbar = (props: HeaderToolbarProps) => { ); return ( - +
    -
    + {titleLink ? ( + + {titleContent} + + ) : ( +
    + {titleContent} +
    )} - ref={toolbarContentRef} - > - - {titleLink ? ( - - {titleContent} - - ) : ( -
    - {titleContent} -
    - )} -
    -
    -
    - {customActions} -
    + +
    +
    + {customActions}
    - +
    ); }; diff --git a/packages/ui/src/components/Header/types.ts b/packages/ui/src/components/Header/types.ts index c7c602abfc..57dd1088f5 100644 --- a/packages/ui/src/components/Header/types.ts +++ b/packages/ui/src/components/Header/types.ts @@ -29,6 +29,7 @@ export interface HeaderProps { customActions?: React.ReactNode; tabs?: HeaderTab[]; onTabSelectionChange?: TabsProps['onSelectionChange']; + className?: string; } /** @@ -59,4 +60,5 @@ export interface HeaderToolbarProps { titleLink?: HeaderProps['titleLink']; customActions?: HeaderProps['customActions']; hasTabs?: boolean; + className?: string; } diff --git a/packages/ui/src/components/HeaderPage/HeaderPage.tsx b/packages/ui/src/components/HeaderPage/HeaderPage.tsx index 271f011a8f..6fcbbe258b 100644 --- a/packages/ui/src/components/HeaderPage/HeaderPage.tsx +++ b/packages/ui/src/components/HeaderPage/HeaderPage.tsx @@ -32,10 +32,12 @@ import clsx from 'clsx'; */ export const HeaderPage = (props: HeaderPageProps) => { const { classNames, cleanedProps } = useStyles('HeaderPage', props); - const { title, tabs, customActions, breadcrumbs } = cleanedProps; + const { className, title, tabs, customActions, breadcrumbs } = cleanedProps; return ( - +
    ((props, ref) => { const navigate = useNavigate(); - const { classNames: classNamesLink } = useStyles('Link', props); - const { - classNames: classNamesText, - dataAttributes: textDataAttributes, - cleanedProps, - } = useStyles('Text', { + const { classNames, dataAttributes, cleanedProps } = useStyles('Link', { variant: 'body', weight: 'regular', color: 'primary', ...props, }); - const { className, variant, weight, color, truncate, href, ...restProps } = - cleanedProps; + + const { className, href, ...restProps } = cleanedProps; const isExternal = isExternalLink(href); + const component = ( + + ); + // If it's an external link, render AriaLink without RouterProvider if (isExternal) { - return ( - - ); + return component; } // For internal links, use RouterProvider return ( - + {component} ); }); diff --git a/packages/ui/src/components/Menu/Menu.module.css b/packages/ui/src/components/Menu/Menu.module.css index f97f3f57ff..606714583e 100644 --- a/packages/ui/src/components/Menu/Menu.module.css +++ b/packages/ui/src/components/Menu/Menu.module.css @@ -188,48 +188,56 @@ } .bui-MenuSearchField { - position: relative; font-family: var(--bui-font-regular); width: 100%; flex-shrink: 0; + display: flex; + align-items: center; + border-bottom: 1px solid var(--bui-border); + background-color: var(--bui-bg-surface-1); + height: 2rem; &[data-empty] { .bui-MenuSearchFieldClear { - display: none; + visibility: hidden; } } } .bui-MenuSearchFieldInput { + flex: 1; display: flex; align-items: center; - padding: 0 var(--bui-space-3); + padding: 0; border: none; - border-bottom: 1px solid var(--bui-border); - background-color: var(--bui-bg-surface-1); + background-color: transparent; font-size: var(--bui-font-size-3); font-family: var(--bui-font-regular); font-weight: var(--bui-font-weight-regular); color: var(--bui-fg-primary); width: 100%; - height: 2rem; - cursor: inherit; + height: 100%; outline: none; + cursor: inherit; &::-webkit-search-cancel-button, &::-webkit-search-decoration { -webkit-appearance: none; } + + &::placeholder { + color: var(--bui-fg-secondary); + } + + &:first-child { + padding-inline: var(--bui-space-3) 0; + } } .bui-MenuSearchFieldClear { - position: absolute; - right: var(--bui-space-2); - top: 0; - bottom: 0; - display: flex; - align-items: center; - justify-content: center; + flex: 0 0 auto; + display: grid; + place-content: center; background-color: transparent; border: none; padding: 0; @@ -237,6 +245,12 @@ cursor: pointer; color: var(--bui-fg-secondary); transition: color 0.2s ease-in-out; + width: 2rem; + height: 2rem; + + &:hover { + color: var(--bui-fg-primary); + } & > svg { width: 1rem; diff --git a/packages/ui/src/components/Menu/Menu.tsx b/packages/ui/src/components/Menu/Menu.tsx index 34eac8a128..6edbeaca20 100644 --- a/packages/ui/src/components/Menu/Menu.tsx +++ b/packages/ui/src/components/Menu/Menu.tsx @@ -86,6 +86,7 @@ export const SubmenuTrigger = (props: SubmenuTriggerProps) => { export const Menu = (props: MenuProps) => { const { classNames, cleanedProps } = useStyles('Menu', props); const { + className, placement = 'bottom start', virtualized = false, maxWidth, @@ -136,7 +137,11 @@ export const Menu = (props: MenuProps) => { return ( ) => { export const MenuListBox = (props: MenuListBoxProps) => { const { classNames, cleanedProps } = useStyles('Menu', props); const { + className, selectionMode = 'single', placement = 'bottom start', virtualized = false, @@ -184,7 +190,11 @@ export const MenuListBox = (props: MenuListBoxProps) => { return ( {virtualized ? ( @@ -207,6 +217,7 @@ export const MenuListBox = (props: MenuListBoxProps) => { export const MenuAutocomplete = (props: MenuAutocompleteProps) => { const { classNames, cleanedProps } = useStyles('Menu', props); const { + className, placement = 'bottom start', virtualized = false, maxWidth, @@ -229,7 +240,11 @@ export const MenuAutocomplete = (props: MenuAutocompleteProps) => { return ( @@ -281,6 +296,7 @@ export const MenuAutocompleteListbox = ( ) => { const { classNames, cleanedProps } = useStyles('Menu', props); const { + className, selectionMode = 'single', placement = 'bottom start', virtualized = false, @@ -304,7 +320,11 @@ export const MenuAutocompleteListbox = ( return ( @@ -352,6 +372,7 @@ export const MenuAutocompleteListbox = ( export const MenuItem = (props: MenuItemProps) => { const { classNames, cleanedProps } = useStyles('Menu', props); const { + className, iconStart, color = 'primary', children, @@ -365,7 +386,7 @@ export const MenuItem = (props: MenuItemProps) => { if (isLink && isExternal) { return ( window.open(href, '_blank', 'noopener,noreferrer')} @@ -398,7 +419,7 @@ export const MenuItem = (props: MenuItemProps) => { return ( { /** @public */ export const MenuListBoxItem = (props: MenuListBoxItemProps) => { const { classNames, cleanedProps } = useStyles('Menu', props); - const { children, ...rest } = cleanedProps; + const { children, className, ...rest } = cleanedProps; return (
    { /** @public */ export const MenuSection = (props: MenuSectionProps) => { const { classNames, cleanedProps } = useStyles('Menu', props); - const { children, title, ...rest } = cleanedProps; + const { children, className, title, ...rest } = cleanedProps; return ( ) => { /** @public */ export const MenuSeparator = (props: MenuSeparatorProps) => { const { classNames, cleanedProps } = useStyles('Menu', props); + const { className, ...rest } = cleanedProps; return ( ); }; diff --git a/packages/ui/src/components/PasswordField/PasswordField.module.css b/packages/ui/src/components/PasswordField/PasswordField.module.css index bf78ab477f..adad950816 100644 --- a/packages/ui/src/components/PasswordField/PasswordField.module.css +++ b/packages/ui/src/components/PasswordField/PasswordField.module.css @@ -23,52 +23,136 @@ font-family: var(--bui-font-regular); width: 100%; flex-shrink: 0; - /* Reserve space for browser/password manager icon (e.g. 1Password) */ - --bui-passwordmanager-icon-width: var(--bui-space-1); + + &[data-size='small'] { + --password-field-item-height: 2rem; + } + + &[data-size='medium'] { + --password-field-item-height: 2.5rem; + } } - .bui-InputVisibility { - position: absolute; - right: var(--bui-passwordmanager-icon-width); - top: 0; - bottom: 0; + .bui-PasswordFieldInputWrapper { + display: flex; + align-items: center; + border-radius: var(--bui-radius-2); + border: 1px solid var(--bui-border); + background-color: var(--bui-bg-surface-1); + transition: border-color 0.2s ease-in-out, outline-color 0.2s ease-in-out; + + &[data-size='small'] { + height: 2rem; + } + + &[data-size='medium'] { + height: 2.5rem; + } + + &:focus-within { + border-color: var(--bui-border-pressed); + outline-width: 0px; + } + + &:hover { + border-color: var(--bui-border-hover); + } + + &:has([data-invalid]) { + border-color: var(--bui-fg-danger); + } + + &:has([data-disabled]) { + opacity: 0.5; + cursor: not-allowed; + border: 1px solid var(--bui-border-disabled); + } + } + + .bui-PasswordFieldIcon { + flex: 0 0 auto; + display: grid; + place-content: center; + color: var(--bui-fg-primary); + pointer-events: none; + width: var(--password-field-item-height); + height: var(--password-field-item-height); + + & svg { + .bui-PasswordField[data-size='small'] & { + width: 1rem; + height: 1rem; + } + + .bui-PasswordField[data-size='medium'] & { + width: 1.25rem; + height: 1.25rem; + } + } + } + + .bui-PasswordFieldInput { + flex: 1; + display: flex; + align-items: center; + padding: 0; + border: none; + background-color: transparent; + font-size: var(--bui-font-size-3); + font-family: var(--bui-font-regular); + font-weight: var(--bui-font-weight-regular); + color: var(--bui-fg-primary); + width: 100%; + height: 100%; + outline: none; + + &::-webkit-search-cancel-button, + &::-webkit-search-decoration { + -webkit-appearance: none; + } + + &::placeholder { + color: var(--bui-fg-secondary); + } + + &[data-disabled] { + cursor: not-allowed; + } + + &:first-child { + .bui-PasswordField[data-size='small'] & { + padding-inline: var(--bui-space-3) 0; + } + + .bui-PasswordField[data-size='medium'] & { + padding-inline: var(--bui-space-4) 0; + } + } + } + + .bui-PasswordFieldVisibility { + flex: 0 0 auto; + display: grid; + place-content: center; background-color: transparent; cursor: pointer; border: none; padding: 0; margin: 0; - display: flex; - align-items: center; - justify-content: center; color: var(--bui-fg-primary); + width: var(--password-field-item-height); + height: var(--password-field-item-height); - /* Size: small */ - &[data-size='small'] { - width: 2rem; - height: 2rem; - } - &[data-size='small'] svg { - width: 1rem; - height: 1rem; - } + & svg { + .bui-PasswordField[data-size='small'] & { + width: 1rem; + height: 1rem; + } - /* Size: medium */ - &[data-size='medium'] { - width: 2.5rem; - height: 2.5rem; + .bui-PasswordField[data-size='medium'] & { + width: 1.25rem; + height: 1.25rem; + } } - &[data-size='medium'] svg { - width: 1.25rem; - height: 1.25rem; - } - } - - /* Ensure input has enough right padding for our toggle + PM icon */ - .bui-PasswordField .bui-InputWrapper[data-size='small'] .bui-Input { - padding-right: calc(2rem + var(--bui-passwordmanager-icon-width)); - } - - .bui-PasswordField .bui-InputWrapper[data-size='medium'] .bui-Input { - padding-right: calc(2.5rem + var(--bui-passwordmanager-icon-width)); } } diff --git a/packages/ui/src/components/PasswordField/PasswordField.tsx b/packages/ui/src/components/PasswordField/PasswordField.tsx index d7cea3a6bd..412128ca32 100644 --- a/packages/ui/src/components/PasswordField/PasswordField.tsx +++ b/packages/ui/src/components/PasswordField/PasswordField.tsx @@ -28,7 +28,6 @@ import type { PasswordFieldProps } from './types'; import { useStyles } from '../../hooks/useStyles'; import { RiEyeLine, RiEyeOffLine } from '@remixicon/react'; import stylesPasswordField from './PasswordField.module.css'; -import stylesTextField from '../TextField/TextField.module.css'; /** @public */ export const PasswordField = forwardRef( @@ -47,8 +46,6 @@ export const PasswordField = forwardRef( } }, [label, ariaLabel, ariaLabelledBy]); - const { classNames: textFieldClassNames } = useStyles('TextField'); - const { classNames: classNamesPasswordField, dataAttributes, @@ -96,16 +93,16 @@ export const PasswordField = forwardRef( />
    {icon && ( )} -
    - setIsVisible(v => !v)} - className={clsx( - classNamesPasswordField.inputVisibility, - stylesPasswordField[classNamesPasswordField.inputVisibility], - )} - > - {isVisible ? : } - -
    + setIsVisible(v => !v)} + className={clsx( + classNamesPasswordField.inputVisibility, + stylesPasswordField[classNamesPasswordField.inputVisibility], + )} + > + {isVisible ? : } +
    diff --git a/packages/ui/src/components/PasswordField/types.ts b/packages/ui/src/components/PasswordField/types.ts index 8af9a6134c..6fade7496a 100644 --- a/packages/ui/src/components/PasswordField/types.ts +++ b/packages/ui/src/components/PasswordField/types.ts @@ -22,7 +22,7 @@ import type { FieldLabelProps } from '../FieldLabel/types'; /** @public */ export interface PasswordFieldProps extends AriaTextFieldProps, - Omit { + Omit { /** * An icon to render before the input */ diff --git a/packages/ui/src/components/Popover/Popover.module.css b/packages/ui/src/components/Popover/Popover.module.css index 873dc33e81..910c2b8c76 100644 --- a/packages/ui/src/components/Popover/Popover.module.css +++ b/packages/ui/src/components/Popover/Popover.module.css @@ -19,7 +19,8 @@ @layer components { .bui-Popover { margin-right: 12px; - overflow: scroll; + overflow-x: hidden; + overflow-y: auto; background-color: var(--bui-bg-surface-1); border: 1px solid var(--bui-border); border-radius: var(--bui-radius-3); diff --git a/packages/ui/src/components/RadioGroup/RadioGroup.module.css b/packages/ui/src/components/RadioGroup/RadioGroup.module.css index acc6d677e4..a18f2d385d 100644 --- a/packages/ui/src/components/RadioGroup/RadioGroup.module.css +++ b/packages/ui/src/components/RadioGroup/RadioGroup.module.css @@ -54,6 +54,8 @@ background: var(--bui-gray-1); border-radius: var(--bui-radius-full); transition: all 200ms; + flex-shrink: 0; + flex-grow: 0; } &[data-pressed]:before { diff --git a/packages/ui/src/components/RadioGroup/types.ts b/packages/ui/src/components/RadioGroup/types.ts index 029ef4baf9..8e2148401f 100644 --- a/packages/ui/src/components/RadioGroup/types.ts +++ b/packages/ui/src/components/RadioGroup/types.ts @@ -24,7 +24,7 @@ import { ReactNode } from 'react'; /** @public */ export interface RadioGroupProps extends Omit, - Omit { + Omit { children?: ReactNode; } diff --git a/packages/ui/src/components/SearchField/SearchField.module.css b/packages/ui/src/components/SearchField/SearchField.module.css index 29ec2cca31..e99c212b29 100644 --- a/packages/ui/src/components/SearchField/SearchField.module.css +++ b/packages/ui/src/components/SearchField/SearchField.module.css @@ -18,11 +18,23 @@ @layer components { .bui-SearchField { + display: flex; + flex-direction: column; + font-family: var(--bui-font-regular); + width: 100%; flex: 1; flex-shrink: 0; + &[data-size='small'] { + --search-field-item-height: 2rem; + } + + &[data-size='medium'] { + --search-field-item-height: 2.5rem; + } + &[data-empty] { - .bui-InputClear { + .bui-SearchFieldClear { display: none; } } @@ -49,20 +61,20 @@ height: 2rem; } - &[data-size='medium'] .bui-Input { + &[data-size='medium'] .bui-SearchFieldInput { &::placeholder { opacity: 0; } } - &[data-size='small'] .bui-Input { + &[data-size='small'] .bui-SearchFieldInput { &::placeholder { opacity: 0; } } - .bui-InputWrapper { - .bui-Input[data-icon] { + .bui-SearchFieldInputWrapper { + .bui-SearchFieldInput[data-icon] { padding-right: 0px; } } @@ -70,48 +82,111 @@ } } - .bui-SearchField .bui-Input { - transition: padding 0.3s ease-in-out, border-color 0.2s ease-in-out, - outline-color 0.2s ease-in-out; - - &[data-hovered] { - border-color: var(--bui-border-hover); - } - - &[data-focused] { - border-color: var(--bui-border-pressed); - outline-width: 0px; - } - } - - .bui-SearchField .bui-InputWrapper { - .bui-Input[data-icon] { - padding-right: var(--bui-space-6); - } - } - - .bui-SearchField .bui-InputIcon { - left: 0; + .bui-SearchFieldInputWrapper { display: flex; - justify-content: center; + align-items: center; + border-radius: var(--bui-radius-2); + border: 1px solid var(--bui-border); + background-color: var(--bui-bg-surface-1); + transition: border-color 0.2s ease-in-out, outline-color 0.2s ease-in-out; &[data-size='small'] { - width: var(--bui-space-8); + height: 2rem; } &[data-size='medium'] { - width: var(--bui-space-10); + height: 2.5rem; + } + + &:focus-within { + border-color: var(--bui-border-pressed); + outline-width: 0px; + } + + &:hover { + border-color: var(--bui-border-hover); + } + + &[data-invalid] { + border-color: var(--bui-fg-danger); + } + + &[data-disabled] { + opacity: 0.5; + cursor: not-allowed; + border: 1px solid var(--bui-border-disabled); } } - .bui-InputClear { - position: absolute; - right: 0; - top: 0; - bottom: 0; + .bui-SearchFieldInputIcon { + flex: 0 0 auto; + display: grid; + place-content: center; + color: var(--bui-fg-primary); + pointer-events: none; + width: var(--search-field-item-height); + height: var(--search-field-item-height); + /* To animate the icon when the input is collapsed */ + transition: opacity 0.2s ease-in-out; + + & svg { + .bui-SearchField[data-size='small'] & { + width: 1rem; + height: 1rem; + } + + .bui-SearchField[data-size='medium'] & { + width: 1.25rem; + height: 1.25rem; + } + } + } + + .bui-SearchFieldInput { + flex: 1; display: flex; align-items: center; - justify-content: center; + padding: 0; + border: none; + background-color: transparent; + font-size: var(--bui-font-size-3); + font-family: var(--bui-font-regular); + font-weight: var(--bui-font-weight-regular); + color: var(--bui-fg-primary); + transition: padding 0.3s ease-in-out; + width: 100%; + height: 100%; + outline: none; + cursor: inherit; + + &::-webkit-search-cancel-button, + &::-webkit-search-decoration { + -webkit-appearance: none; + } + + &::placeholder { + color: var(--bui-fg-secondary); + } + + &[data-disabled] { + cursor: not-allowed; + } + + &:first-child { + .bui-SearchField[data-size='small'] & { + padding-inline: var(--bui-space-3) 0; + } + + .bui-SearchField[data-size='medium'] & { + padding-inline: var(--bui-space-3) 0; + } + } + } + + .bui-SearchFieldClear { + flex: 0 0 auto; + display: grid; + place-content: center; background-color: transparent; border: none; padding: 0; @@ -119,24 +194,16 @@ cursor: pointer; color: var(--bui-fg-secondary); transition: color 0.2s ease-in-out; - } + width: var(--search-field-item-height); + height: var(--search-field-item-height); - .bui-InputClear:hover { - color: var(--bui-fg-primary); - } + &:hover { + color: var(--bui-fg-primary); + } - .bui-InputClear[data-size='small'] { - width: 2rem; - height: 2rem; - } - - .bui-InputClear[data-size='medium'] { - width: 2.5rem; - height: 2.5rem; - } - - .bui-InputClear svg { - width: 1rem; - height: 1rem; + & svg { + width: 1rem; + height: 1rem; + } } } diff --git a/packages/ui/src/components/SearchField/SearchField.tsx b/packages/ui/src/components/SearchField/SearchField.tsx index 820ceb42b9..34fb8c0cee 100644 --- a/packages/ui/src/components/SearchField/SearchField.tsx +++ b/packages/ui/src/components/SearchField/SearchField.tsx @@ -25,8 +25,7 @@ import { FieldLabel } from '../FieldLabel'; import { FieldError } from '../FieldError'; import { RiSearch2Line, RiCloseCircleLine } from '@remixicon/react'; import { useStyles } from '../../hooks/useStyles'; -import stylesSearchField from './SearchField.module.css'; -import stylesTextField from '../TextField/TextField.module.css'; +import styles from './SearchField.module.css'; import type { SearchFieldProps } from './types'; @@ -50,19 +49,15 @@ export const SearchField = forwardRef( } }, [label, ariaLabel, ariaLabelledBy]); - const { classNames: textFieldClassNames } = useStyles('TextField'); - - const { - classNames: searchFieldClassNames, - dataAttributes, - style, - cleanedProps, - } = useStyles('SearchField', { - size: 'small', - placeholder: 'Search', - startCollapsed: false, - ...props, - }); + const { classNames, dataAttributes, style, cleanedProps } = useStyles( + 'SearchField', + { + size: 'small', + placeholder: 'Search', + startCollapsed: false, + ...props, + }, + ); const { className, @@ -101,13 +96,7 @@ export const SearchField = forwardRef( return ( ( />
    {icon !== false && ( )} + - - {options?.map(option => ( - -
    - -
    - - {option.label} - -
    - ))} -
    +
    ); diff --git a/packages/ui/src/components/Select/SelectContent.tsx b/packages/ui/src/components/Select/SelectContent.tsx new file mode 100644 index 0000000000..42070321a3 --- /dev/null +++ b/packages/ui/src/components/Select/SelectContent.tsx @@ -0,0 +1,74 @@ +/* + * Copyright 2025 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 { + Input, + SearchField, + Autocomplete, + Button, +} from 'react-aria-components'; +import { useFilter } from 'react-aria'; +import { RiCloseCircleLine } from '@remixicon/react'; +import clsx from 'clsx'; +import { useStyles } from '../../hooks/useStyles'; +import { SelectListBox } from './SelectListBox'; +import styles from './Select.module.css'; +import type { Option } from './types'; + +interface SelectContentProps { + searchable?: boolean; + searchPlaceholder?: string; + options?: Array