Merge branch 'backstage:master' into patch-2

This commit is contained in:
Valentin Grégoire
2025-06-08 22:14:11 +02:00
committed by GitHub
31 changed files with 186 additions and 69 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/canon': patch
---
Add min-width: 0; by default on every Flex components in Canon to help support truncated texts inside flex elements.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/canon': patch
---
Fix styling for the title4 prop on the Heading component in Canon.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/canon': patch
---
Added a render prop to the Button component in Canon to use it as a link.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-home': patch
---
Fixed the `WelcomeTitle` to properly default to the previous value of `inherit`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Added `backstage.pluginId` field in `package.json` to all default plugin package templates for the `new` command.
+13 -11
View File
@@ -77,11 +77,11 @@ Team: @backstage/helm-chart-maintainers
Scope: The Backstage [Helm Chart(s)](https://github.com/backstage/charts).
| Name | Organization | Team | GitHub | Discord |
| -------------------- | ------------ | ---- | ---------------------------------------- | -------------- |
| Andrew Block | Red Hat | | [sabre1041](http://github.com/sabre1041) | sabre1041#2622 |
| Tom Coufal | Red Hat | | [tumido](http://github.com/tumido) | Tumi#4346 |
| Vincenzo Scamporlino | Spotify | | [vinzscam](http://github.com/vinzscam) | vinzscam#6944 |
| Name | Organization | Team | GitHub | Discord |
| -------------------- | ------------ | ---- | ---------------------------------------- | ---------------- |
| Andrew Block | Red Hat | | [sabre1041](http://github.com/sabre1041) | `sabre1041#2622` |
| Tom Coufal | Red Hat | | [tumido](http://github.com/tumido) | `Tumi#4346` |
| Vincenzo Scamporlino | Spotify | | [vinzscam](http://github.com/vinzscam) | `vinzscam#6944` |
### Home
@@ -89,12 +89,14 @@ Team: @backstage/home-maintainers
Scope: The Backstage home page and information architecture
| Name | Organization | Team | GitHub | Discord |
| ------------------------ | ------------ | -------------- | ---------------------------------------- | ----------------- |
| Avantika Iyer | Spotify | Infinite Buck$ | [tikabom](http://github.com/tikabom) | - |
| Emma Indal | Spotify | Infinite Buck$ | [emmaindal](http://github.com/emmaindal) | emmaindal#7503 |
| Djamaile Rahamat | Spotify | Infinite Buck$ | [djamaile](http://github.com/djamaile) | dyoqi |
| Raghunandan Balachandran | Spotify | Infinite Buck$ | [soapraj](http://github.com/soapraj) | raghunandanb#1114 |
| Name | Organization | Team | GitHub | Discord |
| ------------------ | ------------ | --------------- | ----------------------------------------- | ------- |
| Ainhoa Larumbe | Spotify | Imaginary Goats | [ainhoaL](http://github.com/ainhoaL) | - |
| Avantika Iyer | Spotify | Imaginary Goats | [tikabom](http://github.com/tikabom) | - |
| Daniel Jelčić | Spotify | Imaginary Goats | [djelcic](http://github.com/danieljelcic) | - |
| Eric Peterson | Spotify | Imaginary Goats | [iamEAP](http://github.com/iamEAP) | - |
| Musaab Elfaqih | Spotify | Imaginary Goats | [TheSabby](http://github.com/TheSabby) | - |
| Landry Zinda-Snead | Spotify | Imaginary Goats | [landryzs](http://github.com/landryzs) | - |
### Kubernetes
@@ -125,6 +125,20 @@ Here's a view when buttons are disabled.
code={`<Button disabled>Button</Button>`}
/>
### As Link
Here's a view when buttons are rendered as a link.
<Snippet
align="center"
py={4}
open
preview={<ButtonSnippet story="AsLink" />}
code={`<Button render={<a href="https://canon.backstage.io" target="_blank" />}>
I am a link
</Button>`}
/>
### Responsive
Here's a view when buttons are responsive.
@@ -14,6 +14,12 @@ export const buttonPropDefs: Record<string, PropDef> = {
default: 'medium',
responsive: true,
},
render: {
type: 'enum',
values: ['ReactNode'],
responsive: false,
default: '<button />',
},
...classNamePropDefs,
...stylePropDefs,
};
@@ -59,6 +59,7 @@ appearance of the heading.
<Heading variant="title2">Title 2</Heading>
<Heading variant="title3">Title 3</Heading>
<Heading variant="title4">Title 4</Heading>
<Heading variant="title5">Title 5</Heading>
</Flex>`}
/>
@@ -78,6 +79,17 @@ heading.
</Heading>`}
/>
### Custom render
You can also use the `render` prop to render the heading as a different element.
<Snippet
py={2}
open
preview={<HeadingSnippet story="CustomRender" />}
code={`<Heading render={<h4 />}>Custom render</Heading>`}
/>
### Responsive
You can also use the `variant` prop to change the appearance of the text based
@@ -117,6 +117,16 @@ text.
</Text>`}
/>
### Custom render
You can also use the `render` prop to render the text as a different element.
<Snippet
open
preview={<TextSnippet story="CustomRender" />}
code={`<Text render={<span />}>Custom render</Text>`}
/>
### Responsive
You can also use the `variant` prop to change the appearance of the text based
@@ -8,8 +8,9 @@ description: Documentation for how to convert 3rd-party plugins to support the n
If you are using or want to use a 3rd-party plugin that does not yet support the new frontend system in your app, you can often use conversion utilities from `@backstage/core-compat-api` in order wrap the plugin to make it possible to install in your app.
> [!CAUTION]
> The purpose of these utilities is to wrap 3rd-party plugins. Do not use them for your own plugins where you can add support for the new frontend system directly.
:::caution
The purpose of these utilities is to wrap 3rd-party plugins. Do not use them for your own plugins where you can add support for the new frontend system directly.
:::
## Converting a legacy plugin
+2 -1
View File
@@ -186,6 +186,7 @@
}
.canon-Flex {
min-width: 0;
display: flex;
}
@@ -515,7 +516,7 @@
}
.canon-Heading[data-variant="title4"] {
font-size: var(--canon-font-size-title4);
font-size: var(--canon-font-size-6);
font-weight: var(--canon-font-weight-bold);
}
+1
View File
@@ -1,3 +1,4 @@
.canon-Flex {
min-width: 0;
display: flex;
}
+1 -1
View File
@@ -27,7 +27,7 @@
}
.canon-Heading[data-variant="title4"] {
font-size: var(--canon-font-size-title4);
font-size: var(--canon-font-size-6);
font-weight: var(--canon-font-weight-bold);
}
+2 -1
View File
@@ -9410,6 +9410,7 @@
}
.canon-Flex {
min-width: 0;
display: flex;
}
@@ -9739,7 +9740,7 @@
}
.canon-Heading[data-variant="title4"] {
font-size: var(--canon-font-size-title4);
font-size: var(--canon-font-size-6);
font-weight: var(--canon-font-weight-bold);
}
+2 -4
View File
@@ -149,7 +149,7 @@ export const breakpoints: Breakpoint[];
// @public (undocumented)
export const Button: ForwardRefExoticComponent<
ButtonProps & RefAttributes<HTMLButtonElement>
Omit<ButtonProps, 'ref'> & RefAttributes<HTMLButtonElement>
>;
// @public (undocumented)
@@ -174,9 +174,7 @@ export const buttonPropDefs: {
};
// @public
export interface ButtonProps
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
children: React.ReactNode;
export interface ButtonProps extends useRender.ComponentProps<'button'> {
iconEnd?: ReactElement;
iconStart?: ReactElement;
size?: ButtonOwnProps['size'];
@@ -131,6 +131,18 @@ export const Disabled: Story = {
),
};
export const AsLink: Story = {
args: {
children: 'I am a link',
},
render: args => (
<Button
{...args}
render={<a href="https://canon.backstage.io" target="_blank" />}
/>
),
};
export const Responsive: Story = {
args: {
children: 'Button',
+39 -33
View File
@@ -14,9 +14,10 @@
* limitations under the License.
*/
import { forwardRef } from 'react';
import { forwardRef, useRef } from 'react';
import clsx from 'clsx';
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
import { useRender } from '@base-ui-components/react/use-render';
import type { ButtonProps } from './types';
@@ -26,10 +27,10 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
const {
size = 'small',
variant = 'primary',
disabled,
iconStart,
iconEnd,
children,
render = <button />,
className,
style,
...rest
@@ -38,38 +39,43 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
// Get the responsive value for the variant
const responsiveSize = useResponsiveValue(size);
const responsiveVariant = useResponsiveValue(variant);
const internalRef = useRef<HTMLElement | null>(null);
return (
<button
ref={ref}
disabled={disabled}
className={clsx('canon-Button', className)}
data-size={responsiveSize}
data-variant={responsiveVariant}
style={style}
{...rest}
>
{iconStart && (
<span
className="canon-ButtonIcon"
aria-hidden="true"
data-size={responsiveSize}
>
{iconStart}
</span>
)}
{children}
{iconEnd && (
<span
className="canon-ButtonIcon"
aria-hidden="true"
data-size={responsiveSize}
>
{iconEnd}
</span>
)}
</button>
);
const { renderElement } = useRender({
render,
props: {
className: clsx('canon-Button', className),
['data-variant']: responsiveVariant,
['data-size']: responsiveSize,
...rest,
children: (
<>
{iconStart && (
<span
className="canon-ButtonIcon"
aria-hidden="true"
data-size={responsiveSize}
>
{iconStart}
</span>
)}
{children}
{iconEnd && (
<span
className="canon-ButtonIcon"
aria-hidden="true"
data-size={responsiveSize}
>
{iconEnd}
</span>
)}
</>
),
},
refs: [ref, internalRef],
});
return renderElement();
},
);
@@ -16,14 +16,14 @@
import type { ButtonOwnProps } from './Button.props';
import { ReactElement } from 'react';
import type { useRender } from '@base-ui-components/react/use-render';
/**
* Properties for {@link Button}
*
* @public
*/
export interface ButtonProps
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
export interface ButtonProps extends useRender.ComponentProps<'button'> {
/**
* The size of the button
* @defaultValue 'medium'
@@ -36,11 +36,6 @@ export interface ButtonProps
*/
variant?: ButtonOwnProps['variant'];
/**
* The content of the button
*/
children: React.ReactNode;
/**
* Optional icon to display at the start of the button
*/
@@ -16,6 +16,7 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Flex } from './Flex';
import { Text } from '../Text';
const meta = {
title: 'Layout/Flex',
@@ -143,3 +144,24 @@ export const LargeGap: Story = {
</Flex>
),
};
export const WithTextTruncate: Story = {
render: () => (
<Flex direction="row" gap="8">
<Flex>
<Text truncate>
A man looks at a painting in a museum and says, Brothers and sisters
I have none, but that man&apos;s father is my father&apos;s son. Who
is in the painting?
</Text>
</Flex>
<Flex>
<Text truncate>
A man looks at a painting in a museum and says, Brothers and sisters
I have none, but that man&apos;s father is my father&apos;s son. Who
is in the painting?
</Text>
</Flex>
</Flex>
),
};
@@ -16,4 +16,7 @@
.canon-Flex {
display: flex;
/* This helps when using `truncate` on text inside a flex container */
min-width: 0;
}
@@ -46,6 +46,7 @@ export const AllVariants: Story = {
<Heading variant="title2">Title 2</Heading>
<Heading variant="title3">Title 3</Heading>
<Heading variant="title4">Title 4</Heading>
<Heading variant="title5">Title 5</Heading>
</Flex>
),
};
@@ -43,7 +43,7 @@
}
.canon-Heading[data-variant='title4'] {
font-size: var(--canon-font-size-title4);
font-size: var(--canon-font-size-6);
font-weight: var(--canon-font-weight-bold);
}
@@ -9,7 +9,8 @@
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin-module"
"role": "backend-plugin-module",
"pluginId": "{{pluginId}}"
},
"scripts": {
"start": "backstage-cli package start",
@@ -8,7 +8,8 @@
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin"
"role": "backend-plugin",
"pluginId": "{{pluginId}}"
},
"scripts": {
"start": "backstage-cli package start",
@@ -8,7 +8,8 @@
"types": "dist/index.d.ts"
},
"backstage": {
"role": "frontend-plugin"
"role": "frontend-plugin",
"pluginId": "{{pluginId}}"
},
"sideEffects": false,
"scripts": {
@@ -10,7 +10,8 @@
"types": "dist/index.d.ts"
},
"backstage": {
"role": "common-library"
"role": "common-library",
"pluginId": "{{pluginId}}"
},
"sideEffects": false,
"scripts": {
@@ -9,7 +9,8 @@
"types": "dist/index.d.ts"
},
"backstage": {
"role": "node-library"
"role": "node-library",
"pluginId": "{{pluginId}}"
},
"scripts": {
"build": "backstage-cli package build",
@@ -9,7 +9,8 @@
"types": "dist/index.d.ts"
},
"backstage": {
"role": "web-library"
"role": "web-library",
"pluginId": "{{pluginId}}"
},
"sideEffects": false,
"scripts": {
@@ -9,7 +9,8 @@
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin-module"
"role": "backend-plugin-module",
"pluginId": "scaffolder"
},
"scripts": {
"start": "backstage-cli package start",
@@ -33,7 +33,7 @@ export type WelcomeTitleLanguageProps = {
export const WelcomeTitle = ({
language,
variant,
variant = 'inherit',
}: WelcomeTitleLanguageProps) => {
const identityApi = useApi(identityApiRef);
const alertApi = useApi(alertApiRef);