Skip to content

Commit

Permalink
feat: update setup test headless-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
khoilen committed Jan 17, 2025
1 parent 5bd4d8d commit d5206df
Show file tree
Hide file tree
Showing 13 changed files with 2,191 additions and 994 deletions.
87 changes: 87 additions & 0 deletions apps/nt-headless-ui/components/ui/button/button.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { render, screen } from '@testing-library/react'
import { describe, expect, it } from 'vitest'

import { Button } from './button'

describe('Button', () => {
it('renders correctly with default props', () => {
render(<Button>Click me</Button>)
const button = screen.getByRole('button', {
name: /click me/i,
})
expect(button).toBeInTheDocument()
expect(button).toHaveClass('bg-primary text-white')
})

it('renders with primary variant and default size', () => {
render(<Button variant="primary">Primary Button</Button>)
const button = screen.getByRole('button', {
name: /primary button/i,
})
expect(button).toHaveClass('bg-primary text-white')
})

it('renders with secondary variant', () => {
render(<Button variant="secondary">Secondary Button</Button>)
const button = screen.getByRole('button', {
name: /secondary button/i,
})
expect(button).toHaveClass('bg-shade-secondary-1 text-white')
})

it('renders with outline variant', () => {
render(<Button variant="outline">Outline Button</Button>)
const button = screen.getByRole('button', {
name: /outline button/i,
})
expect(button).toHaveClass(
'border border-primary text-primary',
)
})

it('renders with different sizes', () => {
render(<Button size="sm">Small Button</Button>)
const button = screen.getByRole('button', {
name: /small button/i,
})
expect(button).toHaveClass('h-8 px-3 text-xs')

render(<Button size="lg">Large Button</Button>)
const largeButton = screen.getByRole('button', {
name: /large button/i,
})
expect(largeButton).toHaveClass('h-10 px-8')
})

it('renders with an icon on the left', () => {
render(
<Button icon={<span>Icon</span>}>
Button with Icon
</Button>,
)
const button = screen.getByRole('button', {
name: /button with icon/i,
})
expect(button).toContainHTML('<span>Icon</span>')
})

it('renders with an icon on the right', () => {
render(
<Button icon={<span>Icon</span>} iconPosition="right">
Button with Icon
</Button>,
)
const button = screen.getByRole('button', {
name: /button with icon/i,
})
expect(button).toContainHTML('<span>Icon</span>')
})

it('renders as disabled', () => {
render(<Button disabled>Disabled Button</Button>)
const button = screen.getByRole('button', {
name: /disabled button/i,
})
expect(button).toBeDisabled()
})
})
12 changes: 11 additions & 1 deletion apps/nt-headless-ui/components/ui/button/button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Primary.args = {
export const Secondary: StoryFn<ButtonProps> = Template.bind({})
Secondary.args = {
onClick: () => alert('Button clicked!'),
variant: 'seconadry',
variant: 'secondary',
}

export const Outline: StoryFn<ButtonProps> = Template.bind({})
Expand All @@ -37,3 +37,13 @@ OutlineSecondary.args = {
onClick: () => alert('Button clicked!'),
variant: 'outline-secondary',
}
export const WithIcon: StoryFn<ButtonProps> = Template.bind({})
WithIcon.args = {
onClick: () => alert('Button with icon clicked!'),
variant: 'primary',
icon: (
<span role="img" aria-label="icon">
🚀
</span>
),
}
31 changes: 23 additions & 8 deletions apps/nt-headless-ui/components/ui/button/button.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { cn } from '@/lib/utils'
import { Slot } from '@radix-ui/react-slot'
import { cva, type VariantProps } from 'class-variance-authority'
import * as React from 'react'

const buttonVariants = cva(
'inline-flex items-center justify-center rounded-badge text-sm font-medium shadow-md',
'inline-flex items-center justify-center rounded-md text-sm font-medium shadow-md',
{
variants: {
variant: {
primary:
'bg-primary text-white hover:bg-shade-primary-80 active:bg-shade-primary-110 disabled:bg-shade-primary-20 disabled:text-white',
seconadry:
secondary:
'bg-shade-secondary-1 text-white hover:bg-shade-secondary-1-80 active:bg-shade-secondary-1-110 disabled:bg-shade-secondary-1-20 disabled:text-white',
outline:
'border border-primary text-primary hover:shadow active:bg-shade-primary-10 disabled:bg-primary-20 disabled:text-white',
Expand All @@ -34,23 +33,39 @@ const buttonVariants = cva(
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
icon?: React.ReactNode
iconPosition?: 'left' | 'right'
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{ className, variant, size, asChild = false, ...props },
{
className,
variant,
size,
icon = null,
iconPosition = 'left',
children,
...props
},
ref,
) => {
const Comp = asChild ? Slot : 'button'
return (
<Comp
<button
className={cn(
buttonVariants({ variant, size, className }),
)}
ref={ref}
{...props}
/>
>
{icon && iconPosition === 'left' && (
<span className="mr-2">{icon}</span>
)}
{children}
{icon && iconPosition === 'right' && (
<span className="ml-2">{icon}</span>
)}
</button>
)
},
)
Expand Down
7 changes: 4 additions & 3 deletions apps/nt-headless-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
"name": "@nashtech/headless-ui",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"build": "next build",
"start": "next start",
"lint": "next lint",
"dev": "storybook dev -p 6006 -c .storybook",
"build-storybook": "storybook -c .storybook -o dist/storybook"
"build-storybook": "storybook -c .storybook -o dist/storybook",
"test": "npx vitest"
},
"dependencies": {
"@radix-ui/react-slot": "^1.1.1",
Expand All @@ -19,6 +21,7 @@
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
Expand All @@ -33,8 +36,6 @@
"@types/react": "^19",
"@types/react-dom": "^19",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.17",
"typescript": "^5",
"webpack": "5"
}
Expand Down
Loading

0 comments on commit d5206df

Please sign in to comment.