diff --git a/components/src/atoms/buttons/EmptySelectorButton.stories.tsx b/components/src/atoms/buttons/EmptySelectorButton.stories.tsx new file mode 100644 index 00000000000..75a70ba602b --- /dev/null +++ b/components/src/atoms/buttons/EmptySelectorButton.stories.tsx @@ -0,0 +1,45 @@ +import * as React from 'react' +import { Box } from '../../primitives' +import { EmptySelectorButton as EmptySelectorButtonComponent } from './EmptySelectorButton' +import type { Meta, StoryObj } from '@storybook/react' + +const meta: Meta = { + title: 'Library/Atoms/Buttons/EmptySelectorButton', + component: EmptySelectorButtonComponent, + argTypes: { + size: { + control: { + type: 'select', + options: ['large', 'small'], + }, + defaultValue: 'large', + }, + textAlignment: { + controls: { + type: 'select', + options: ['left', 'middle'], + }, + defaultValue: 'left', + }, + }, + decorators: [ + (Story, context) => ( + + + + ), + ], +} +export default meta + +type Story = StoryObj + +export const EmptySelectorButton: Story = { + args: { + text: 'mock text', + iconName: 'plus', + size: 'small', + textAlignment: 'left', + onClick: () => {}, + }, +} diff --git a/components/src/atoms/buttons/EmptySelectorButton.tsx b/components/src/atoms/buttons/EmptySelectorButton.tsx new file mode 100644 index 00000000000..8c3adc765b0 --- /dev/null +++ b/components/src/atoms/buttons/EmptySelectorButton.tsx @@ -0,0 +1,59 @@ +import * as React from 'react' +import { Flex } from '../../primitives' +import { + BORDERS, + COLORS, + Icon, + SPACING, + StyledText, + Btn, + JUSTIFY_CENTER, + JUSTIFY_START, + ALIGN_CENTER, + FLEX_MAX_CONTENT, +} from '../..' +import type { IconName } from '../..' + +interface EmptySelectorButtonProps { + onClick: () => void + text: string + textAlignment: 'left' | 'middle' + iconName?: IconName + size?: 'large' | 'small' +} + +// used for helix and Opentrons Ai +export function EmptySelectorButton( + props: EmptySelectorButtonProps +): JSX.Element { + const { onClick, text, iconName, size = 'large', textAlignment } = props + const buttonSizing = size === 'large' ? '100%' : FLEX_MAX_CONTENT + + return ( + + + {iconName != null ? ( + + ) : null} + {text} + + + ) +} diff --git a/components/src/atoms/buttons/__tests__/EmptySelectorButton.test.tsx b/components/src/atoms/buttons/__tests__/EmptySelectorButton.test.tsx new file mode 100644 index 00000000000..a1833c7181f --- /dev/null +++ b/components/src/atoms/buttons/__tests__/EmptySelectorButton.test.tsx @@ -0,0 +1,44 @@ +import * as React from 'react' +import '@testing-library/jest-dom/vitest' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { renderWithProviders } from '../../../testing/utils' +import { JUSTIFY_CENTER, JUSTIFY_START } from '../../../styles' +import { EmptySelectorButton } from '../EmptySelectorButton' + +const render = (props: React.ComponentProps) => { + return renderWithProviders()[0] +} + +describe('EmptySelectorButton', () => { + let props: React.ComponentProps + beforeEach(() => { + props = { + onClick: vi.fn(), + text: 'mock text', + iconName: 'add', + textAlignment: 'left', + size: 'large', + } + }) + it('renders the props and button cta', () => { + render(props) + const button = screen.getByText('mock text') + fireEvent.click(button) + expect(props.onClick).toHaveBeenCalled() + screen.getByTestId('EmptySelectorButton_add') + expect(screen.getByTestId('EmptySelectorButton_container')).toHaveStyle( + `justify-content: ${JUSTIFY_START}` + ) + }) + it('renders middled aligned button', () => { + props.textAlignment = 'middle' + props.size = 'small' + props.iconName = undefined + render(props) + expect(screen.getByTestId('EmptySelectorButton_container')).toHaveStyle( + `justify-content: ${JUSTIFY_CENTER}` + ) + screen.queryByTestId('EmptySelectorButton_add') + }) +}) diff --git a/components/src/atoms/buttons/index.ts b/components/src/atoms/buttons/index.ts index b4a7d0b1c49..b29312f5f8c 100644 --- a/components/src/atoms/buttons/index.ts +++ b/components/src/atoms/buttons/index.ts @@ -1,4 +1,5 @@ export * from './AlertPrimaryButton' +export * from './EmptySelectorButton' export * from './LargeButton' export * from './PrimaryButton' export * from './RadioButton'