diff --git a/.changeset/nice-vans-vanish.md b/.changeset/nice-vans-vanish.md
new file mode 100644
index 0000000000..c52fc42488
--- /dev/null
+++ b/.changeset/nice-vans-vanish.md
@@ -0,0 +1,5 @@
+---
+'@backstage/canon': minor
+---
+
+**Breaking Change** Icons on Button and IconButton now need to be imported and placed like this: } />
diff --git a/packages/canon/css/button.css b/packages/canon/css/button.css
index eb0c44ce1b..7aaad3ec48 100644
--- a/packages/canon/css/button.css
+++ b/packages/canon/css/button.css
@@ -78,12 +78,12 @@
height: 32px;
}
-.canon-Button[data-size="small"] .canon-ButtonIcon {
+.canon-ButtonIcon[data-size="small"], .canon-ButtonIcon[data-size="small"] svg {
width: 1rem;
height: 1rem;
}
-.canon-Button[data-size="medium"] .canon-ButtonIcon {
- width: 1.5rem;
- height: 1.5rem;
+.canon-ButtonIcon[data-size="medium"], .canon-ButtonIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
diff --git a/packages/canon/css/components.css b/packages/canon/css/components.css
index f67d0b332d..f4c8008673 100644
--- a/packages/canon/css/components.css
+++ b/packages/canon/css/components.css
@@ -134,14 +134,14 @@
height: 32px;
}
-.canon-Button[data-size="small"] .canon-ButtonIcon {
+.canon-ButtonIcon[data-size="small"], .canon-ButtonIcon[data-size="small"] svg {
width: 1rem;
height: 1rem;
}
-.canon-Button[data-size="medium"] .canon-ButtonIcon {
- width: 1.5rem;
- height: 1.5rem;
+.canon-ButtonIcon[data-size="medium"], .canon-ButtonIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
.canon-CollapsiblePanel {
@@ -521,14 +521,14 @@
height: 32px;
}
-.canon-IconButton[data-size="small"] .canon-IconButtonIcon {
+.canon-IconButtonIcon[data-size="small"], .canon-IconButtonIcon[data-size="small"] svg {
width: 1rem;
height: 1rem;
}
-.canon-IconButton[data-size="medium"] .canon-IconButtonIcon {
- width: 1.5rem;
- height: 1.5rem;
+.canon-IconButtonIcon[data-size="medium"], .canon-IconButtonIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
.canon-TextField {
diff --git a/packages/canon/css/iconbutton.css b/packages/canon/css/iconbutton.css
index e867a1848e..dc3f9d94c5 100644
--- a/packages/canon/css/iconbutton.css
+++ b/packages/canon/css/iconbutton.css
@@ -78,12 +78,12 @@
height: 32px;
}
-.canon-IconButton[data-size="small"] .canon-IconButtonIcon {
+.canon-IconButtonIcon[data-size="small"], .canon-IconButtonIcon[data-size="small"] svg {
width: 1rem;
height: 1rem;
}
-.canon-IconButton[data-size="medium"] .canon-IconButtonIcon {
- width: 1.5rem;
- height: 1.5rem;
+.canon-IconButtonIcon[data-size="medium"], .canon-IconButtonIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
diff --git a/packages/canon/css/styles.css b/packages/canon/css/styles.css
index 0fa08102fd..141bc1b5fb 100644
--- a/packages/canon/css/styles.css
+++ b/packages/canon/css/styles.css
@@ -9358,14 +9358,14 @@
height: 32px;
}
-.canon-Button[data-size="small"] .canon-ButtonIcon {
+.canon-ButtonIcon[data-size="small"], .canon-ButtonIcon[data-size="small"] svg {
width: 1rem;
height: 1rem;
}
-.canon-Button[data-size="medium"] .canon-ButtonIcon {
- width: 1.5rem;
- height: 1.5rem;
+.canon-ButtonIcon[data-size="medium"], .canon-ButtonIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
.canon-CollapsiblePanel {
@@ -9745,14 +9745,14 @@
height: 32px;
}
-.canon-IconButton[data-size="small"] .canon-IconButtonIcon {
+.canon-IconButtonIcon[data-size="small"], .canon-IconButtonIcon[data-size="small"] svg {
width: 1rem;
height: 1rem;
}
-.canon-IconButton[data-size="medium"] .canon-IconButtonIcon {
- width: 1.5rem;
- height: 1.5rem;
+.canon-IconButtonIcon[data-size="medium"], .canon-IconButtonIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
.canon-TextField {
diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md
index 0a315ae105..765a77148f 100644
--- a/packages/canon/report.api.md
+++ b/packages/canon/report.api.md
@@ -15,6 +15,7 @@ import { ForwardRefExoticComponent } from 'react';
import { HTMLAttributes } from 'react';
import { JSX as JSX_2 } from 'react/jsx-runtime';
import { Menu as Menu_2 } from '@base-ui-components/react/menu';
+import { ReactElement } from 'react';
import { ReactNode } from 'react';
import { RefAttributes } from 'react';
import type { RemixiconComponentType } from '@remixicon/react';
@@ -173,8 +174,8 @@ export const buttonPropDefs: {
export interface ButtonProps
extends Omit, 'children'> {
children: React.ReactNode;
- iconEnd?: IconNames;
- iconStart?: IconNames;
+ iconEnd?: ReactElement;
+ iconStart?: ReactElement;
size?: ButtonOwnProps['size'];
variant?: ButtonOwnProps['variant'];
}
@@ -697,7 +698,7 @@ export const iconButtonPropDefs: {
// @public
export interface IconButtonProps
extends Omit, 'children'> {
- icon: IconNames;
+ icon: ReactElement;
size?: IconButtonOwnProps['size'];
variant?: IconButtonOwnProps['variant'];
}
diff --git a/packages/canon/src/components/Button/Button.stories.tsx b/packages/canon/src/components/Button/Button.stories.tsx
index 7377ad497d..fffc31b488 100644
--- a/packages/canon/src/components/Button/Button.stories.tsx
+++ b/packages/canon/src/components/Button/Button.stories.tsx
@@ -19,6 +19,7 @@ import { Button } from './Button';
import { Flex } from '../Flex';
import { Text } from '../Text';
import { ButtonProps } from './types';
+import { Icon } from '../Icon';
const meta = {
title: 'Components/Button',
@@ -55,10 +56,10 @@ export const Variants: Story = {
},
render: () => (
-
-
+ } variant="secondary">
Button
@@ -71,8 +72,12 @@ export const Sizes: Story = {
},
render: () => (
- Medium
- Small
+ }>
+ Medium
+
+ }>
+ Small
+
),
};
@@ -83,9 +88,13 @@ export const WithIcons: Story = {
},
render: args => (
-
-
-
+ } />
+ } />
+ }
+ iconEnd={}
+ />
),
};
@@ -96,9 +105,13 @@ export const FullWidth: Story = {
},
render: args => (
-
-
-
+ } />
+ } />
+ }
+ iconEnd={}
+ />
),
};
@@ -150,22 +163,22 @@ export const Playground: Story = {
Button
}
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
>
Button
}
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
>
Button
}
+ iconEnd={}
style={{ width: '200px' }}
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
@@ -180,7 +193,7 @@ export const Playground: Story = {
Button
}
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
disabled
@@ -188,7 +201,7 @@ export const Playground: Story = {
Button
}
variant={variant as ButtonProps['variant']}
size={size as ButtonProps['size']}
disabled
diff --git a/packages/canon/src/components/Button/Button.tsx b/packages/canon/src/components/Button/Button.tsx
index ca652013b4..ab70f168c8 100644
--- a/packages/canon/src/components/Button/Button.tsx
+++ b/packages/canon/src/components/Button/Button.tsx
@@ -15,7 +15,6 @@
*/
import { forwardRef } from 'react';
-import { Icon } from '../Icon';
import clsx from 'clsx';
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
@@ -50,9 +49,25 @@ export const Button = forwardRef(
style={style}
{...rest}
>
- {iconStart && }
+ {iconStart && (
+
+ {iconStart}
+
+ )}
{children}
- {iconEnd && }
+ {iconEnd && (
+
+ {iconEnd}
+
+ )}
);
},
diff --git a/packages/canon/src/components/Button/styles.css b/packages/canon/src/components/Button/styles.css
index 785fbf3b88..a4afd85c9b 100644
--- a/packages/canon/src/components/Button/styles.css
+++ b/packages/canon/src/components/Button/styles.css
@@ -94,12 +94,14 @@
height: 32px;
}
-.canon-Button[data-size='small'] .canon-ButtonIcon {
+.canon-ButtonIcon[data-size='small'],
+.canon-ButtonIcon[data-size='small'] svg {
width: 1rem;
height: 1rem;
}
-.canon-Button[data-size='medium'] .canon-ButtonIcon {
- width: 1.5rem;
- height: 1.5rem;
+.canon-ButtonIcon[data-size='medium'],
+.canon-ButtonIcon[data-size='medium'] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
diff --git a/packages/canon/src/components/Button/types.ts b/packages/canon/src/components/Button/types.ts
index 0d61e1cda4..4ab62d5683 100644
--- a/packages/canon/src/components/Button/types.ts
+++ b/packages/canon/src/components/Button/types.ts
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { IconNames } from '../Icon';
+
import type { ButtonOwnProps } from './Button.props';
+import { ReactElement } from 'react';
/**
* Properties for {@link Button}
@@ -43,10 +44,10 @@ export interface ButtonProps
/**
* Optional icon to display at the start of the button
*/
- iconStart?: IconNames;
+ iconStart?: ReactElement;
/**
* Optional icon to display at the end of the button
*/
- iconEnd?: IconNames;
+ iconEnd?: ReactElement;
}
diff --git a/packages/canon/src/components/Collapsible/Collapsible.stories.tsx b/packages/canon/src/components/Collapsible/Collapsible.stories.tsx
index 4130419a0c..175dadba85 100644
--- a/packages/canon/src/components/Collapsible/Collapsible.stories.tsx
+++ b/packages/canon/src/components/Collapsible/Collapsible.stories.tsx
@@ -19,6 +19,7 @@ import { Collapsible } from './';
import { Button } from '../Button';
import { Box } from '../Box';
import { Text } from '../Text';
+import { Icon } from '../Icon';
const meta = {
title: 'Components/Collapsible',
@@ -42,7 +43,13 @@ export const Default: Story = {
render={(props, state) => (
+ ) : (
+
+ )
+ }
{...props}
>
{state.open ? 'Close Panel' : 'Open Panel'}
diff --git a/packages/canon/src/components/DataTable/Pagination/DataTablePagination.tsx b/packages/canon/src/components/DataTable/Pagination/DataTablePagination.tsx
index 2e8d47c1dc..2efa73bf14 100644
--- a/packages/canon/src/components/DataTable/Pagination/DataTablePagination.tsx
+++ b/packages/canon/src/components/DataTable/Pagination/DataTablePagination.tsx
@@ -21,6 +21,7 @@ import { IconButton } from '../../IconButton';
import clsx from 'clsx';
import { Select } from '../../Select';
import { useDataTable } from '../Root/DataTableRoot';
+import { Icon } from '../../Icon';
/** @public */
const DataTablePagination = forwardRef(
@@ -75,14 +76,14 @@ const DataTablePagination = forwardRef(
size="small"
onClick={() => table?.previousPage()}
disabled={!table?.getCanPreviousPage()}
- icon="chevron-left"
+ icon={}
/>
table?.nextPage()}
disabled={!table?.getCanNextPage()}
- icon="chevron-right"
+ icon={}
/>
diff --git a/packages/canon/src/components/IconButton/IconButton.stories.tsx b/packages/canon/src/components/IconButton/IconButton.stories.tsx
index edac9bd7e8..d16dcd1fcb 100644
--- a/packages/canon/src/components/IconButton/IconButton.stories.tsx
+++ b/packages/canon/src/components/IconButton/IconButton.stories.tsx
@@ -19,6 +19,7 @@ import { IconButton } from './IconButton';
import { Flex } from '../Flex';
import { Text } from '../Text';
import { IconButtonProps } from './types';
+import { Icon } from '../Icon';
const meta = {
title: 'Components/IconButton',
@@ -44,7 +45,8 @@ type Story = StoryObj;
export const Variants: Story = {
args: {
- icon: 'cloud',
+ icon: ,
+ 'aria-label': 'Cloud icon button',
},
parameters: {
argTypes: {
@@ -63,7 +65,8 @@ export const Variants: Story = {
export const Sizes: Story = {
args: {
- icon: 'cloud',
+ icon: ,
+ 'aria-label': 'Cloud icon button',
},
render: args => (
@@ -75,8 +78,9 @@ export const Sizes: Story = {
export const Disabled: Story = {
args: {
- icon: 'cloud',
+ icon: ,
disabled: true,
+ 'aria-label': 'Cloud icon button',
},
render: args => (
@@ -88,7 +92,8 @@ export const Disabled: Story = {
export const Responsive: Story = {
args: {
- icon: 'cloud',
+ icon: ,
+ 'aria-label': 'Cloud icon button',
variant: {
initial: 'primary',
sm: 'secondary',
@@ -104,7 +109,8 @@ const variants: string[] = ['primary', 'secondary'];
export const Playground: Story = {
args: {
- icon: 'cloud',
+ icon: ,
+ 'aria-label': 'Cloud icon button',
},
render: args => (
@@ -120,13 +126,15 @@ export const Playground: Story = {
/>
}
+ aria-label="Chevron right icon button"
variant={variant as IconButtonProps['variant']}
size={size as IconButtonProps['size']}
/>
}
+ aria-label="Chevron right icon button"
variant={variant as IconButtonProps['variant']}
size={size as IconButtonProps['size']}
/>
diff --git a/packages/canon/src/components/IconButton/IconButton.tsx b/packages/canon/src/components/IconButton/IconButton.tsx
index b2581844bc..bca012cac0 100644
--- a/packages/canon/src/components/IconButton/IconButton.tsx
+++ b/packages/canon/src/components/IconButton/IconButton.tsx
@@ -15,7 +15,6 @@
*/
import { forwardRef } from 'react';
-import { Icon } from '../Icon';
import clsx from 'clsx';
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
@@ -45,7 +44,13 @@ export const IconButton = forwardRef(
style={style}
{...rest}
>
-
+
+ {icon}
+
);
},
diff --git a/packages/canon/src/components/IconButton/styles.css b/packages/canon/src/components/IconButton/styles.css
index 859c512fd6..066b0fbad5 100644
--- a/packages/canon/src/components/IconButton/styles.css
+++ b/packages/canon/src/components/IconButton/styles.css
@@ -94,12 +94,14 @@
width: 32px;
}
-.canon-IconButton[data-size='small'] .canon-IconButtonIcon {
+.canon-IconButtonIcon[data-size='small'],
+.canon-IconButtonIcon[data-size='small'] svg {
width: 1rem;
height: 1rem;
}
-.canon-IconButton[data-size='medium'] .canon-IconButtonIcon {
- width: 1.5rem;
- height: 1.5rem;
+.canon-IconButtonIcon[data-size='medium'],
+.canon-IconButtonIcon[data-size='medium'] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
diff --git a/packages/canon/src/components/IconButton/types.ts b/packages/canon/src/components/IconButton/types.ts
index 90505d3352..ece1950d1b 100644
--- a/packages/canon/src/components/IconButton/types.ts
+++ b/packages/canon/src/components/IconButton/types.ts
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { IconNames } from '../Icon';
+
import type { IconButtonOwnProps } from './IconButton.props';
+import { ReactElement } from 'react';
/**
* Properties for {@link IconButton}
@@ -36,7 +37,7 @@ export interface IconButtonProps
variant?: IconButtonOwnProps['variant'];
/**
- * Icon to display at the start of the button
+ * Icon to display in the button
*/
- icon: IconNames;
+ icon: ReactElement;
}
diff --git a/packages/canon/src/components/Menu/Menu.stories.tsx b/packages/canon/src/components/Menu/Menu.stories.tsx
index d1b8f831c5..5d04a2f19c 100644
--- a/packages/canon/src/components/Menu/Menu.stories.tsx
+++ b/packages/canon/src/components/Menu/Menu.stories.tsx
@@ -17,6 +17,7 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Menu } from './Menu';
import { Button } from '../Button';
+import { Icon } from '../Icon';
const meta = {
title: 'Components/Menu',
@@ -36,7 +37,7 @@ export const Default: Story = {
{...props}
size="medium"
variant="secondary"
- iconEnd="chevron-down"
+ iconEnd={}
>
Menu