From 9f19c7784a06928ccdc210445d9a990fcc393b09 Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Mon, 8 Jun 2026 08:59:31 +0400 Subject: [PATCH] feat: Select component --- .../components/Select/Select.stories.tsx | 57 ++++++++++ .../shared/components/Select/Select.test.tsx | 58 ++++++++++ .../src/shared/components/Select/index.tsx | 107 ++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 packages/react-kit/src/shared/components/Select/Select.stories.tsx create mode 100644 packages/react-kit/src/shared/components/Select/Select.test.tsx create mode 100644 packages/react-kit/src/shared/components/Select/index.tsx diff --git a/packages/react-kit/src/shared/components/Select/Select.stories.tsx b/packages/react-kit/src/shared/components/Select/Select.stories.tsx new file mode 100644 index 00000000..364f402c --- /dev/null +++ b/packages/react-kit/src/shared/components/Select/Select.stories.tsx @@ -0,0 +1,57 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' + +import { Select } from '.' + +const meta = { + title: 'Shared/Select', + component: Select, + parameters: { layout: 'centered' }, + tags: ['autodocs'], + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + args: { + label: 'Token', + }, +} + +export const WithLeadingImageAndChain: Story = { + args: { + label: 'Token', + subtitle: 'Arbitrum', + leadingImage: + 'https://img.icons8.com/external-black-fill-lafs/64/external-USDC-cryptocurrency-black-fill-lafs.png', + chainImage: 'https://img.icons8.com/color/1200/ethereum.jpg', + }, +} + +export const NoTrailingIcon: Story = { + args: { + label: 'Token', + trailingIcon: false, + }, +} + +export const Disabled: Story = { + args: { + label: 'Token', + disabled: true, + }, +} + +export const Loading: Story = { + args: { + label: '', + loading: true, + }, +} diff --git a/packages/react-kit/src/shared/components/Select/Select.test.tsx b/packages/react-kit/src/shared/components/Select/Select.test.tsx new file mode 100644 index 00000000..7df1b27b --- /dev/null +++ b/packages/react-kit/src/shared/components/Select/Select.test.tsx @@ -0,0 +1,58 @@ +/** + * @vitest-environment happy-dom + */ +import { cleanup, fireEvent, render, screen } from '@testing-library/react' +import { afterEach, describe, expect, it, vi } from 'vitest' + +import { Select } from '.' + +afterEach(() => cleanup()) + +describe('Select', () => { + it('renders the label', () => { + render() + fireEvent.click(screen.getByRole('button')) + expect(onClick).toHaveBeenCalledTimes(1) + }) + + it('renders subtitle and chain image when provided', () => { + render( + ) + expect(container.querySelector('svg')).toBeDefined() + }) + + it('hides the trailing icon when trailingIcon=false', () => { + const { container } = render() + fireEvent.click(screen.getByRole('button')) + expect(onClick).not.toHaveBeenCalled() + }) + + it('renders the skeleton when loading', () => { + render(