diff --git a/canon-docs/src/content/components/switch.mdx b/canon-docs/src/content/components/switch.mdx
new file mode 100644
index 0000000000..068ec96217
--- /dev/null
+++ b/canon-docs/src/content/components/switch.mdx
@@ -0,0 +1,41 @@
+import { PropsTable } from '@/components/PropsTable';
+import { Snippet } from '@/components/Snippet';
+import { CodeBlock } from '@/components/CodeBlock';
+import { SwitchSnippet } from '@/snippets/stories-snippets';
+import { switchPropDefs, snippetUsage } from './switch.props';
+import { ComponentInfos } from '@/components/ComponentInfos';
+
+# Switch
+
+A control that indicates whether a setting is on or off.
+
+}
+ code={``}
+/>
+
+
+
+## API reference
+
+
+
+## Examples
+
+### Disabled
+
+A switch can be disabled using the `isDisabled` prop.
+
+}
+ code={``}
+/>
diff --git a/canon-docs/src/content/components/switch.props.ts b/canon-docs/src/content/components/switch.props.ts
new file mode 100644
index 0000000000..ddbca4e049
--- /dev/null
+++ b/canon-docs/src/content/components/switch.props.ts
@@ -0,0 +1,71 @@
+import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs';
+import type { PropDef } from '@/utils/propDefs';
+
+export const switchPropDefs: Record = {
+ autoFocus: {
+ type: 'boolean',
+ },
+ defaultSelected: {
+ type: 'boolean',
+ },
+ ...classNamePropDefs,
+ isDisabled: {
+ type: 'boolean',
+ },
+ isReadOnly: {
+ type: 'boolean',
+ },
+ isSelected: {
+ type: 'boolean',
+ },
+ label: {
+ type: 'string',
+ },
+ name: {
+ type: 'string',
+ },
+ onChange: {
+ type: 'enum',
+ values: ['(isSelected: boolean) => void'],
+ },
+ onFocus: {
+ type: 'enum',
+ values: ['(e: FocusEvent) => void'],
+ },
+ onBlur: {
+ type: 'enum',
+ values: ['(e: FocusEvent) => void'],
+ },
+ onFocusChange: {
+ type: 'enum',
+ values: ['(isFocused: boolean) => void'],
+ },
+ onKeyDown: {
+ type: 'enum',
+ values: ['(e: KeyboardEvent) => void'],
+ },
+ onKeyUp: {
+ type: 'enum',
+ values: ['(e: KeyboardEvent) => void'],
+ },
+ onHoverStart: {
+ type: 'enum',
+ values: ['(e: HoverEvent) => void'],
+ },
+ onHoverEnd: {
+ type: 'enum',
+ values: ['(e: HoverEvent) => void'],
+ },
+ onHoverChange: {
+ type: 'enum',
+ values: ['(isHovered: boolean) => void'],
+ },
+ ...stylePropDefs,
+ value: {
+ type: 'string',
+ },
+};
+
+export const snippetUsage = `import { Switch } from '@backstage/canon';
+
+`;
diff --git a/canon-docs/src/snippets/stories-snippets.tsx b/canon-docs/src/snippets/stories-snippets.tsx
index 64047ebde9..95738a6330 100644
--- a/canon-docs/src/snippets/stories-snippets.tsx
+++ b/canon-docs/src/snippets/stories-snippets.tsx
@@ -18,6 +18,7 @@ import * as LinkStories from '../../../packages/canon/src/components/Link/Link.s
import * as AvatarStories from '../../../packages/canon/src/components/Avatar/Avatar.stories';
import * as CollapsibleStories from '../../../packages/canon/src/components/Collapsible/Collapsible.stories';
import * as TabsStories from '../../../packages/canon/src/components/Tabs/Tabs.stories';
+import * as SwitchStories from '../../../packages/canon/src/components/Switch/Switch.stories';
export const BoxSnippet = ({ story }: { story: keyof typeof BoxStories }) => {
const stories = composeStories(BoxStories);
@@ -173,3 +174,14 @@ export const TabsSnippet = ({ story }: { story: keyof typeof TabsStories }) => {
return StoryComponent ? : null;
};
+
+export const SwitchSnippet = ({
+ story,
+}: {
+ story: keyof typeof SwitchStories;
+}) => {
+ const stories = composeStories(SwitchStories);
+ const StoryComponent = stories[story as keyof typeof stories];
+
+ return StoryComponent ? : null;
+};
diff --git a/canon-docs/src/utils/changelog.ts b/canon-docs/src/utils/changelog.ts
index 1c15f5c264..94317ab78b 100644
--- a/canon-docs/src/utils/changelog.ts
+++ b/canon-docs/src/utils/changelog.ts
@@ -17,7 +17,8 @@ export type Component =
| 'link'
| 'tooltip'
| 'scrollarea'
- | 'flex';
+ | 'flex'
+ | 'switch';
export type Version = `${number}.${number}.${number}`;
@@ -30,6 +31,13 @@ export interface ChangelogProps {
}
export const changelog: ChangelogProps[] = [
+ {
+ components: ['switch'],
+ version: '0.5.0',
+ description: '✨ Add new `Switch` component',
+ platform: 'portal',
+ prs: ['30251'],
+ },
{
components: ['tabs'],
version: '0.4.0',
diff --git a/canon-docs/src/utils/data.ts b/canon-docs/src/utils/data.ts
index 58f44f764d..20ff9146a7 100644
--- a/canon-docs/src/utils/data.ts
+++ b/canon-docs/src/utils/data.ts
@@ -116,6 +116,11 @@ export const components: Page[] = [
slug: 'select',
status: 'alpha',
},
+ {
+ title: 'Switch',
+ slug: 'switch',
+ status: 'alpha',
+ },
{
title: 'Table',
slug: 'table',
diff --git a/packages/canon/src/components/Switch/Switch.stories.tsx b/packages/canon/src/components/Switch/Switch.stories.tsx
index 8350d0f4e5..165fefc97b 100644
--- a/packages/canon/src/components/Switch/Switch.stories.tsx
+++ b/packages/canon/src/components/Switch/Switch.stories.tsx
@@ -30,3 +30,10 @@ export const Default: Story = {
label: 'Switch',
},
};
+
+export const Disabled: Story = {
+ args: {
+ ...Default.args,
+ isDisabled: true,
+ },
+};