diff --git a/.changeset/spotty-papers-call.md b/.changeset/spotty-papers-call.md
new file mode 100644
index 0000000000..3e39e8e1f8
--- /dev/null
+++ b/.changeset/spotty-papers-call.md
@@ -0,0 +1,5 @@
+---
+'@backstage/canon': minor
+---
+
+The icon prop in TextField now accept a ReactNode instead of an icon name. We also updated the icon sizes for each input sizes.
diff --git a/canon-docs/src/app/(docs)/components/text-field/page.mdx b/canon-docs/src/app/(docs)/components/text-field/page.mdx
index bd5fa31025..ed857def4e 100644
--- a/canon-docs/src/app/(docs)/components/text-field/page.mdx
+++ b/canon-docs/src/app/(docs)/components/text-field/page.mdx
@@ -33,9 +33,16 @@ A text field component for your forms.
We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with
your brand. For additional flexibility, you can use the provided class names for each element listed below.
- `}
- />
+ - `canon-TextField`
+ - `canon-TextFieldLabel`
+ - `canon-TextFieldRequired`
+ - `canon-TextFieldInputWrapper`
+ - `canon-TextFieldIcon`
+ - `canon-TextFieldInput`
+ - `canon-TextFieldClearButton`
+ - `canon-TextFieldClearButtonIcon`
+ - `canon-TextFieldDescription`
+ - `canon-TextFieldError`
@@ -55,8 +62,8 @@ We support two different sizes: `small`, `medium`.
open
preview={}
code={`
-
-
+ } />
+ } />
`}
/>
diff --git a/canon-docs/src/app/(docs)/components/text-field/props.ts b/canon-docs/src/app/(docs)/components/text-field/props.ts
index cafed21189..74dec9d5e6 100644
--- a/canon-docs/src/app/(docs)/components/text-field/props.ts
+++ b/canon-docs/src/app/(docs)/components/text-field/props.ts
@@ -5,12 +5,16 @@ export const inputPropDefs: Record = {
size: {
type: 'enum',
values: ['small', 'medium'],
- default: 'medium',
- responsive: false,
+ default: 'small',
+ responsive: true,
},
label: {
type: 'string',
},
+ icon: {
+ type: 'enum',
+ values: ['ReactNode'],
+ },
description: {
type: 'string',
},
diff --git a/packages/canon/css/components.css b/packages/canon/css/components.css
index 6aae715633..d479444df9 100644
--- a/packages/canon/css/components.css
+++ b/packages/canon/css/components.css
@@ -576,13 +576,20 @@
display: flex;
}
-.canon-TextFieldInputIcon {
- padding-right: var(--canon-space-1);
- width: 1.5rem;
- height: 1.5rem;
+.canon-TextFieldIcon {
+ margin-right: var(--canon-space-1);
color: var(--canon-fg-primary);
flex-shrink: 0;
- display: block;
+}
+
+.canon-TextFieldIcon[data-size="small"], .canon-TextFieldIcon[data-size="small"] svg {
+ width: 1rem;
+ height: 1rem;
+}
+
+.canon-TextFieldIcon[data-size="medium"], .canon-TextFieldIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
.canon-TextFieldInput {
diff --git a/packages/canon/css/styles.css b/packages/canon/css/styles.css
index 5fb6a934cb..6c53aaa198 100644
--- a/packages/canon/css/styles.css
+++ b/packages/canon/css/styles.css
@@ -9800,13 +9800,20 @@
display: flex;
}
-.canon-TextFieldInputIcon {
- padding-right: var(--canon-space-1);
- width: 1.5rem;
- height: 1.5rem;
+.canon-TextFieldIcon {
+ margin-right: var(--canon-space-1);
color: var(--canon-fg-primary);
flex-shrink: 0;
- display: block;
+}
+
+.canon-TextFieldIcon[data-size="small"], .canon-TextFieldIcon[data-size="small"] svg {
+ width: 1rem;
+ height: 1rem;
+}
+
+.canon-TextFieldIcon[data-size="medium"], .canon-TextFieldIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
.canon-TextFieldInput {
diff --git a/packages/canon/css/textfield.css b/packages/canon/css/textfield.css
index a2980d6beb..c3c1a88ad6 100644
--- a/packages/canon/css/textfield.css
+++ b/packages/canon/css/textfield.css
@@ -43,13 +43,20 @@
display: flex;
}
-.canon-TextFieldInputIcon {
- padding-right: var(--canon-space-1);
- width: 1.5rem;
- height: 1.5rem;
+.canon-TextFieldIcon {
+ margin-right: var(--canon-space-1);
color: var(--canon-fg-primary);
flex-shrink: 0;
- display: block;
+}
+
+.canon-TextFieldIcon[data-size="small"], .canon-TextFieldIcon[data-size="small"] svg {
+ width: 1rem;
+ height: 1rem;
+}
+
+.canon-TextFieldIcon[data-size="medium"], .canon-TextFieldIcon[data-size="medium"] svg {
+ width: 1.25rem;
+ height: 1.25rem;
}
.canon-TextFieldInput {
diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md
index da1b5015b4..cbbdd4db33 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 type { MouseEventHandler } from 'react';
import { ReactElement } from 'react';
import { ReactNode } from 'react';
import { RefAttributes } from 'react';
@@ -1220,10 +1221,10 @@ export interface TextFieldProps
className?: string;
description?: string;
error?: string | null;
- icon?: IconNames;
+ icon?: ReactNode;
label?: string;
name: string;
- onClear?: React.MouseEventHandler;
+ onClear?: MouseEventHandler;
size?: 'small' | 'medium' | Partial>;
}
diff --git a/packages/canon/src/components/TextField/TextField.stories.tsx b/packages/canon/src/components/TextField/TextField.stories.tsx
index 0615a157a1..7e625dad24 100644
--- a/packages/canon/src/components/TextField/TextField.stories.tsx
+++ b/packages/canon/src/components/TextField/TextField.stories.tsx
@@ -17,6 +17,7 @@
import type { Meta, StoryObj } from '@storybook/react';
import { TextField } from './TextField';
import { Flex } from '../Flex';
+import { Icon } from '../Icon';
const meta = {
title: 'Components/TextField',
@@ -79,8 +80,8 @@ export const Sizes: Story = {
},
render: args => (
-
-
+ } />
+ } />
),
};
@@ -114,7 +115,7 @@ export const WithIcon: Story = {
args: {
...WithLabel.args,
placeholder: 'Search...',
- icon: 'search',
+ icon: ,
},
};
diff --git a/packages/canon/src/components/TextField/TextField.styles.css b/packages/canon/src/components/TextField/TextField.styles.css
index ad3ccc931b..be7ec3379c 100644
--- a/packages/canon/src/components/TextField/TextField.styles.css
+++ b/packages/canon/src/components/TextField/TextField.styles.css
@@ -59,15 +59,24 @@
background-color: var(--canon-bg-surface-1);
}
-.canon-TextFieldInputIcon {
- display: block;
- padding-right: var(--canon-space-1);
- width: 1.5rem;
- height: 1.5rem;
+.canon-TextFieldIcon {
+ margin-right: var(--canon-space-1);
color: var(--canon-fg-primary);
flex-shrink: 0;
}
+.canon-TextFieldIcon[data-size='small'],
+.canon-TextFieldIcon[data-size='small'] svg {
+ width: 1rem;
+ height: 1rem;
+}
+
+.canon-TextFieldIcon[data-size='medium'],
+.canon-TextFieldIcon[data-size='medium'] svg {
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
.canon-TextFieldInput {
border: none;
background: none;
diff --git a/packages/canon/src/components/TextField/TextField.tsx b/packages/canon/src/components/TextField/TextField.tsx
index bb32033da4..e4cf43a711 100644
--- a/packages/canon/src/components/TextField/TextField.tsx
+++ b/packages/canon/src/components/TextField/TextField.tsx
@@ -27,7 +27,7 @@ export const TextField = forwardRef(
(props: TextFieldProps, ref) => {
const {
className,
- size = 'medium',
+ size = 'small',
label,
description,
error,
@@ -61,7 +61,15 @@ export const TextField = forwardRef(
)}
- {icon &&
}
+ {icon && (
+
+ {icon}
+
+ )}
, 'size'> {
@@ -54,10 +53,10 @@ export interface TextFieldProps
/**
* An icon to render before the input
*/
- icon?: IconNames;
+ icon?: ReactNode;
/**
* Handler to call when the clear button is pressed
*/
- onClear?: React.MouseEventHandler;
+ onClear?: MouseEventHandler;
}