@aiready/components 0.14.4 → 0.14.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/charts/ForceDirectedGraph.js.map +1 -1
  2. package/dist/components/checkbox.js +3 -1
  3. package/dist/components/checkbox.js.map +1 -1
  4. package/dist/components/separator.js +1 -0
  5. package/dist/components/separator.js.map +1 -1
  6. package/dist/components/switch.js +64 -42
  7. package/dist/components/switch.js.map +1 -1
  8. package/dist/hooks/useForceSimulation.js.map +1 -1
  9. package/dist/index.js +68 -43
  10. package/dist/index.js.map +1 -1
  11. package/package.json +2 -2
  12. package/src/charts/force-directed/useGraphInteractions.ts +2 -2
  13. package/src/charts/force-directed/useImperativeHandle.ts +1 -1
  14. package/src/components/__tests__/badge.test.tsx +38 -0
  15. package/src/components/__tests__/button.test.tsx +54 -0
  16. package/src/components/__tests__/card.test.tsx +56 -17
  17. package/src/components/__tests__/checkbox.test.tsx +28 -58
  18. package/src/components/__tests__/container.test.tsx +44 -51
  19. package/src/components/__tests__/grid.test.tsx +27 -134
  20. package/src/components/__tests__/input.test.tsx +35 -20
  21. package/src/components/__tests__/label.test.tsx +29 -35
  22. package/src/components/__tests__/modal.test.tsx +43 -72
  23. package/src/components/__tests__/select.test.tsx +51 -84
  24. package/src/components/__tests__/separator.test.tsx +23 -56
  25. package/src/components/__tests__/switch.test.tsx +28 -68
  26. package/src/components/__tests__/textarea.test.tsx +29 -77
  27. package/src/components/checkbox.tsx +3 -1
  28. package/src/components/separator.tsx +1 -0
  29. package/src/components/switch.tsx +62 -41
  30. package/src/hooks/useForceSimulation.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/components",
3
- "version": "0.14.4",
3
+ "version": "0.14.6",
4
4
  "description": "Unified shared components library (UI, charts, hooks, utilities) for AIReady",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -128,7 +128,7 @@
128
128
  "framer-motion": "^12.35.0",
129
129
  "lucide-react": "^0.577.0",
130
130
  "tailwind-merge": "^3.0.0",
131
- "@aiready/core": "0.24.5"
131
+ "@aiready/core": "0.24.7"
132
132
  },
133
133
  "devDependencies": {
134
134
  "@testing-library/jest-dom": "^6.6.5",
@@ -35,7 +35,7 @@ export function useGraphZoom(
35
35
  const svg = d3.select(svgRef.current);
36
36
  const g = d3.select(gRef.current);
37
37
 
38
- const zoom = (d3 as any)
38
+ const zoom = (d3 as typeof d3)
39
39
  .zoom()
40
40
  .scaleExtent([0.1, 10])
41
41
  .on('zoom', (event: any) => {
@@ -44,7 +44,7 @@ export function useGraphZoom(
44
44
  setTransform(event.transform);
45
45
  });
46
46
 
47
- svg.call(zoom);
47
+ svg.call(zoom as unknown as any);
48
48
 
49
49
  return () => {
50
50
  svg.on('.zoom', null);
@@ -92,7 +92,7 @@ export function useImperativeHandleMethods({
92
92
  svg
93
93
  .transition()
94
94
  .duration(TRANSITION_DURATION_MS)
95
- .call((d3 as any).zoom().transform as any, newTransform);
95
+ .call(d3.zoom().transform as any, newTransform);
96
96
  setTransform(newTransform);
97
97
  }
98
98
  }, [nodes, width, height, svgRef, gRef, setTransform]);
@@ -0,0 +1,38 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { Badge } from '../badge';
4
+
5
+ describe('Badge', () => {
6
+ it('renders badge with text', () => {
7
+ render(<Badge>New</Badge>);
8
+ expect(screen.getByText('New')).toBeInTheDocument();
9
+ });
10
+
11
+ it('applies custom className', () => {
12
+ render(<Badge className="custom-badge">Test</Badge>);
13
+ expect(screen.getByText('Test')).toHaveClass('custom-badge');
14
+ });
15
+
16
+ it('renders with default variant', () => {
17
+ render(<Badge data-testid="badge">Default</Badge>);
18
+ const badge = screen.getByTestId('badge');
19
+ expect(badge).toBeInTheDocument();
20
+ });
21
+
22
+ it('renders with different variants', () => {
23
+ const { rerender } = render(<Badge variant="secondary">Secondary</Badge>);
24
+ expect(screen.getByText('Secondary')).toBeInTheDocument();
25
+
26
+ rerender(<Badge variant="destructive">Destructive</Badge>);
27
+ expect(screen.getByText('Destructive')).toBeInTheDocument();
28
+
29
+ rerender(<Badge variant="outline">Outline</Badge>);
30
+ expect(screen.getByText('Outline')).toBeInTheDocument();
31
+ });
32
+
33
+ it('renders as inline element', () => {
34
+ render(<Badge>Inline</Badge>);
35
+ const badge = screen.getByText('Inline');
36
+ expect(badge).toHaveClass('inline-flex');
37
+ });
38
+ });
@@ -0,0 +1,54 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { Button, buttonVariants } from '../button';
4
+
5
+ describe('Button', () => {
6
+ it('renders with default variant', () => {
7
+ render(<Button>Click me</Button>);
8
+ expect(screen.getByRole('button')).toHaveTextContent('Click me');
9
+ });
10
+
11
+ it('applies custom className', () => {
12
+ render(<Button className="custom-class">Test</Button>);
13
+ expect(screen.getByRole('button')).toHaveClass('custom-class');
14
+ });
15
+
16
+ it('renders with different variants', () => {
17
+ const { rerender } = render(<Button variant="destructive">Delete</Button>);
18
+ expect(screen.getByRole('button')).toBeInTheDocument();
19
+
20
+ rerender(<Button variant="outline">Outline</Button>);
21
+ expect(screen.getByRole('button')).toBeInTheDocument();
22
+
23
+ rerender(<Button variant="ghost">Ghost</Button>);
24
+ expect(screen.getByRole('button')).toBeInTheDocument();
25
+ });
26
+
27
+ it('renders with different sizes', () => {
28
+ const { rerender } = render(<Button size="sm">Small</Button>);
29
+ expect(screen.getByRole('button')).toBeInTheDocument();
30
+
31
+ rerender(<Button size="lg">Large</Button>);
32
+ expect(screen.getByRole('button')).toBeInTheDocument();
33
+
34
+ rerender(<Button size="icon">I</Button>);
35
+ expect(screen.getByRole('button')).toBeInTheDocument();
36
+ });
37
+
38
+ it('forwards ref correctly', () => {
39
+ const ref = { current: null };
40
+ render(<Button ref={ref}>Ref</Button>);
41
+ expect(ref.current).toBeInstanceOf(HTMLButtonElement);
42
+ });
43
+
44
+ it('is disabled when disabled prop is true', () => {
45
+ render(<Button disabled>Disabled</Button>);
46
+ expect(screen.getByRole('button')).toBeDisabled();
47
+ });
48
+
49
+ it('buttonVariants returns correct class string', () => {
50
+ const classes = buttonVariants({ variant: 'default', size: 'default' });
51
+ expect(typeof classes).toBe('string');
52
+ expect(classes.length).toBeGreaterThan(0);
53
+ });
54
+ });
@@ -1,31 +1,70 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import { render, screen } from '@testing-library/react';
3
- import { Card } from '../card';
3
+ import {
4
+ Card,
5
+ CardHeader,
6
+ CardTitle,
7
+ CardDescription,
8
+ CardContent,
9
+ CardFooter,
10
+ } from '../card';
4
11
 
5
12
  describe('Card', () => {
6
- it('should render children content', () => {
7
- render(<Card>Test Content</Card>);
8
- expect(screen.getByText('Test Content')).toBeInTheDocument();
13
+ it('renders card with children', () => {
14
+ render(<Card>Card content</Card>);
15
+ expect(screen.getByText('Card content')).toBeInTheDocument();
9
16
  });
10
17
 
11
- it('should apply custom className', () => {
12
- const { container } = render(<Card className="custom-class">Content</Card>);
13
- expect(container.firstChild).toHaveClass('custom-class');
18
+ it('applies custom className', () => {
19
+ render(<Card className="custom">Test</Card>);
20
+ expect(screen.getByText('Test')).toHaveClass('custom');
14
21
  });
15
22
 
16
- it('should render with default styles', () => {
17
- const { container } = render(<Card>Content</Card>);
18
- expect(container.firstChild).toBeInTheDocument();
23
+ it('renders full card structure', () => {
24
+ render(
25
+ <Card>
26
+ <CardHeader>
27
+ <CardTitle>Title</CardTitle>
28
+ <CardDescription>Description</CardDescription>
29
+ </CardHeader>
30
+ <CardContent>Content</CardContent>
31
+ <CardFooter>Footer</CardFooter>
32
+ </Card>
33
+ );
34
+
35
+ expect(screen.getByText('Title')).toBeInTheDocument();
36
+ expect(screen.getByText('Description')).toBeInTheDocument();
37
+ expect(screen.getByText('Content')).toBeInTheDocument();
38
+ expect(screen.getByText('Footer')).toBeInTheDocument();
39
+ });
40
+
41
+ it('CardHeader renders with correct class', () => {
42
+ render(<CardHeader data-testid="header">Header</CardHeader>);
43
+ expect(screen.getByTestId('header')).toHaveClass(
44
+ 'flex',
45
+ 'flex-col',
46
+ 'space-y-1.5'
47
+ );
48
+ });
49
+
50
+ it('CardTitle renders as heading', () => {
51
+ render(<CardTitle>My Title</CardTitle>);
52
+ const title = screen.getByText('My Title');
53
+ expect(title).toBeInTheDocument();
54
+ });
55
+
56
+ it('CardDescription renders with muted styling', () => {
57
+ render(<CardDescription>Description text</CardDescription>);
58
+ expect(screen.getByText('Description text')).toBeInTheDocument();
19
59
  });
20
60
 
21
- it('should forward ref', () => {
22
- const ref = { current: null };
23
- render(<Card ref={ref}>Content</Card>);
24
- expect(ref.current).not.toBeNull();
61
+ it('CardContent renders with correct padding', () => {
62
+ render(<CardContent data-testid="content">Content</CardContent>);
63
+ expect(screen.getByTestId('content')).toHaveClass('pt-0');
25
64
  });
26
65
 
27
- it('should spread additional props', () => {
28
- const { container } = render(<Card data-testid="card">Content</Card>);
29
- expect(container.firstChild).toHaveAttribute('data-testid', 'card');
66
+ it('CardFooter renders with flex layout', () => {
67
+ render(<CardFooter data-testid="footer">Footer</CardFooter>);
68
+ expect(screen.getByTestId('footer')).toHaveClass('flex', 'items-center');
30
69
  });
31
70
  });
@@ -1,75 +1,45 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { render, screen, fireEvent } from '@testing-library/react';
1
+ import { describe, it, expect } from 'vitest';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import { Checkbox } from '../checkbox';
4
4
 
5
5
  describe('Checkbox', () => {
6
- it('should render a checkbox input', () => {
7
- render(<Checkbox />);
8
- expect(screen.getByRole('checkbox')).toBeInTheDocument();
6
+ it('renders checkbox', () => {
7
+ render(<Checkbox data-testid="checkbox" />);
8
+ expect(screen.getByTestId('checkbox')).toBeInTheDocument();
9
9
  });
10
10
 
11
- it('should render with a label', () => {
12
- render(<Checkbox label="Accept terms" />);
13
- expect(screen.getByLabelText('Accept terms')).toBeInTheDocument();
11
+ it('applies custom className', () => {
12
+ render(<Checkbox className="custom-checkbox" data-testid="checkbox" />);
13
+ expect(screen.getByTestId('checkbox')).toHaveClass('custom-checkbox');
14
14
  });
15
15
 
16
- it('should not render label when not provided', () => {
17
- const { container } = render(<Checkbox />);
18
- expect(container.querySelector('label')).not.toBeInTheDocument();
16
+ it('renders with checkbox role', () => {
17
+ render(<Checkbox data-testid="checkbox" />);
18
+ const checkbox = screen.getByTestId('checkbox');
19
+ expect(checkbox).toHaveAttribute('role', 'checkbox');
19
20
  });
20
21
 
21
- it('should apply custom className', () => {
22
- const { container } = render(<Checkbox className="custom-class" />);
23
- expect(container.querySelector('input')).toHaveClass('custom-class');
22
+ it('has unchecked state by default', () => {
23
+ render(<Checkbox data-testid="checkbox" />);
24
+ const checkbox = screen.getByTestId('checkbox');
25
+ expect(checkbox).toHaveAttribute('aria-checked', 'false');
24
26
  });
25
27
 
26
- it('should handle checked state', () => {
27
- render(<Checkbox checked readOnly />);
28
- expect(screen.getByRole('checkbox')).toBeChecked();
28
+ it('can be checked', () => {
29
+ render(<Checkbox checked data-testid="checkbox" />);
30
+ const checkbox = screen.getByTestId('checkbox');
31
+ expect(checkbox).toHaveAttribute('aria-checked', 'true');
29
32
  });
30
33
 
31
- it('should handle unchecked state', () => {
32
- render(<Checkbox checked={false} readOnly />);
33
- expect(screen.getByRole('checkbox')).not.toBeChecked();
34
+ it('is disabled when disabled prop is true', () => {
35
+ render(<Checkbox disabled data-testid="checkbox" />);
36
+ const checkbox = screen.getByTestId('checkbox');
37
+ expect(checkbox).toBeDisabled();
34
38
  });
35
39
 
36
- it('should call onChange when clicked', () => {
37
- const handleChange = vi.fn();
38
- render(<Checkbox onChange={handleChange} />);
39
- fireEvent.click(screen.getByRole('checkbox'));
40
- expect(handleChange).toHaveBeenCalledTimes(1);
41
- });
42
-
43
- it('should be disabled when disabled prop is set', () => {
44
- render(<Checkbox disabled />);
45
- expect(screen.getByRole('checkbox')).toBeDisabled();
46
- });
47
-
48
- it('should forward ref', () => {
49
- const ref = { current: null };
50
- render(<Checkbox ref={ref} />);
51
- expect(ref.current).not.toBeNull();
52
- });
53
-
54
- it('should spread additional props', () => {
55
- const { container } = render(<Checkbox data-testid="checkbox" />);
56
- expect(container.querySelector('input')).toHaveAttribute(
57
- 'data-testid',
58
- 'checkbox'
59
- );
60
- });
61
-
62
- it('should use provided id', () => {
63
- render(<Checkbox id="custom-id" label="Test" />);
64
- const checkbox = screen.getByRole('checkbox');
65
- const label = screen.getByText('Test');
66
- expect(checkbox).toHaveAttribute('id', 'custom-id');
67
- expect(label).toHaveAttribute('for', 'custom-id');
68
- });
69
-
70
- it('should generate unique id when not provided', () => {
71
- render(<Checkbox label="Test" />);
72
- const checkbox = screen.getByRole('checkbox');
73
- expect(checkbox).toHaveAttribute('id');
40
+ it('has default styling', () => {
41
+ render(<Checkbox data-testid="checkbox" />);
42
+ const checkbox = screen.getByTestId('checkbox');
43
+ expect(checkbox).toHaveClass('peer', 'h-4', 'w-4');
74
44
  });
75
45
  });
@@ -3,68 +3,61 @@ import { render, screen } from '@testing-library/react';
3
3
  import { Container } from '../container';
4
4
 
5
5
  describe('Container', () => {
6
- it('should render children content', () => {
7
- render(<Container>Test Content</Container>);
8
- expect(screen.getByText('Test Content')).toBeInTheDocument();
9
- });
10
-
11
- it('should apply custom className', () => {
12
- const { container } = render(
13
- <Container className="custom-class">Content</Container>
6
+ it('renders container with children', () => {
7
+ render(
8
+ <Container>
9
+ <div>Content</div>
10
+ </Container>
14
11
  );
15
- expect(container.firstChild).toHaveClass('custom-class');
16
- });
17
-
18
- it('should render with default lg size', () => {
19
- const { container } = render(<Container>Content</Container>);
20
- expect(container.firstChild).toHaveClass('max-w-screen-lg');
21
- });
22
-
23
- it('should render with sm size', () => {
24
- const { container } = render(<Container size="sm">Content</Container>);
25
- expect(container.firstChild).toHaveClass('max-w-screen-sm');
26
- });
27
-
28
- it('should render with md size', () => {
29
- const { container } = render(<Container size="md">Content</Container>);
30
- expect(container.firstChild).toHaveClass('max-w-screen-md');
12
+ expect(screen.getByText('Content')).toBeInTheDocument();
31
13
  });
32
14
 
33
- it('should render with xl size', () => {
34
- const { container } = render(<Container size="xl">Content</Container>);
35
- expect(container.firstChild).toHaveClass('max-w-screen-xl');
36
- });
37
-
38
- it('should render with full size', () => {
39
- const { container } = render(<Container size="full">Content</Container>);
40
- expect(container.firstChild).toHaveClass('max-w-full');
41
- });
42
-
43
- it('should have responsive padding classes', () => {
44
- const { container } = render(<Container>Content</Container>);
45
- expect(container.firstChild).toHaveClass('px-4', 'sm:px-6', 'lg:px-8');
15
+ it('applies custom className', () => {
16
+ render(
17
+ <Container className="custom-container" data-testid="container">
18
+ <div>Content</div>
19
+ </Container>
20
+ );
21
+ expect(screen.getByTestId('container')).toHaveClass('custom-container');
46
22
  });
47
23
 
48
- it('should be centered with mx-auto', () => {
49
- const { container } = render(<Container>Content</Container>);
50
- expect(container.firstChild).toHaveClass('mx-auto');
24
+ it('renders as div element', () => {
25
+ render(
26
+ <Container data-testid="container">
27
+ <div>Content</div>
28
+ </Container>
29
+ );
30
+ const container = screen.getByTestId('container');
31
+ expect(container.tagName).toBe('DIV');
51
32
  });
52
33
 
53
- it('should have full width', () => {
54
- const { container } = render(<Container>Content</Container>);
55
- expect(container.firstChild).toHaveClass('w-full');
34
+ it('has default container styling', () => {
35
+ render(
36
+ <Container data-testid="container">
37
+ <div>Content</div>
38
+ </Container>
39
+ );
40
+ const container = screen.getByTestId('container');
41
+ expect(container).toHaveClass('mx-auto', 'w-full');
56
42
  });
57
43
 
58
- it('should forward ref', () => {
59
- const ref = { current: null };
60
- render(<Container ref={ref}>Content</Container>);
61
- expect(ref.current).not.toBeNull();
44
+ it('has padding by default', () => {
45
+ render(
46
+ <Container data-testid="container">
47
+ <div>Content</div>
48
+ </Container>
49
+ );
50
+ const container = screen.getByTestId('container');
51
+ expect(container).toHaveClass('px-4');
62
52
  });
63
53
 
64
- it('should spread additional props', () => {
65
- const { container } = render(
66
- <Container data-testid="container">Content</Container>
54
+ it('applies size prop', () => {
55
+ render(
56
+ <Container size="sm" data-testid="container">
57
+ <div>Content</div>
58
+ </Container>
67
59
  );
68
- expect(container.firstChild).toHaveAttribute('data-testid', 'container');
60
+ const container = screen.getByTestId('container');
61
+ expect(container).toHaveClass('max-w-screen-sm');
69
62
  });
70
63
  });
@@ -3,7 +3,7 @@ import { render, screen } from '@testing-library/react';
3
3
  import { Grid } from '../grid';
4
4
 
5
5
  describe('Grid', () => {
6
- it('should render children content', () => {
6
+ it('renders grid with children', () => {
7
7
  render(
8
8
  <Grid>
9
9
  <div>Item 1</div>
@@ -14,159 +14,52 @@ describe('Grid', () => {
14
14
  expect(screen.getByText('Item 2')).toBeInTheDocument();
15
15
  });
16
16
 
17
- it('should apply custom className', () => {
18
- const { container } = render(
19
- <Grid className="custom-class">
20
- <div>Content</div>
21
- </Grid>
22
- );
23
- expect(container.firstChild).toHaveClass('custom-class');
24
- });
25
-
26
- it('should render with default 3 columns', () => {
27
- const { container } = render(
28
- <Grid>
29
- <div>Content</div>
30
- </Grid>
31
- );
32
- expect(container.firstChild).toHaveClass(
33
- 'grid-cols-1',
34
- 'sm:grid-cols-2',
35
- 'lg:grid-cols-3'
36
- );
37
- });
38
-
39
- it('should render with 1 column', () => {
40
- const { container } = render(
41
- <Grid cols={1}>
42
- <div>Content</div>
43
- </Grid>
44
- );
45
- expect(container.firstChild).toHaveClass('grid-cols-1');
46
- });
47
-
48
- it('should render with 2 columns', () => {
49
- const { container } = render(
50
- <Grid cols={2}>
51
- <div>Content</div>
52
- </Grid>
53
- );
54
- expect(container.firstChild).toHaveClass('grid-cols-1', 'sm:grid-cols-2');
55
- });
56
-
57
- it('should render with 4 columns', () => {
58
- const { container } = render(
59
- <Grid cols={4}>
60
- <div>Content</div>
61
- </Grid>
62
- );
63
- expect(container.firstChild).toHaveClass(
64
- 'grid-cols-1',
65
- 'sm:grid-cols-2',
66
- 'lg:grid-cols-4'
67
- );
68
- });
69
-
70
- it('should render with 5 columns', () => {
71
- const { container } = render(
72
- <Grid cols={5}>
73
- <div>Content</div>
74
- </Grid>
75
- );
76
- expect(container.firstChild).toHaveClass(
77
- 'grid-cols-1',
78
- 'sm:grid-cols-2',
79
- 'lg:grid-cols-5'
80
- );
81
- });
82
-
83
- it('should render with 6 columns', () => {
84
- const { container } = render(
85
- <Grid cols={6}>
86
- <div>Content</div>
87
- </Grid>
88
- );
89
- expect(container.firstChild).toHaveClass(
90
- 'grid-cols-1',
91
- 'sm:grid-cols-2',
92
- 'lg:grid-cols-6'
93
- );
94
- });
95
-
96
- it('should render with 12 columns', () => {
97
- const { container } = render(
98
- <Grid cols={12}>
99
- <div>Content</div>
100
- </Grid>
101
- );
102
- expect(container.firstChild).toHaveClass(
103
- 'grid-cols-1',
104
- 'sm:grid-cols-2',
105
- 'lg:grid-cols-12'
106
- );
107
- });
108
-
109
- it('should render with default md gap', () => {
110
- const { container } = render(
111
- <Grid>
112
- <div>Content</div>
113
- </Grid>
114
- );
115
- expect(container.firstChild).toHaveClass('gap-4');
116
- });
117
-
118
- it('should render with sm gap', () => {
119
- const { container } = render(
120
- <Grid gap="sm">
121
- <div>Content</div>
122
- </Grid>
123
- );
124
- expect(container.firstChild).toHaveClass('gap-2');
125
- });
126
-
127
- it('should render with lg gap', () => {
128
- const { container } = render(
129
- <Grid gap="lg">
17
+ it('applies custom className', () => {
18
+ render(
19
+ <Grid className="custom-grid" data-testid="grid">
130
20
  <div>Content</div>
131
21
  </Grid>
132
22
  );
133
- expect(container.firstChild).toHaveClass('gap-6');
23
+ expect(screen.getByTestId('grid')).toHaveClass('custom-grid');
134
24
  });
135
25
 
136
- it('should render with xl gap', () => {
137
- const { container } = render(
138
- <Grid gap="xl">
139
- <div>Content</div>
26
+ it('renders with default columns', () => {
27
+ render(
28
+ <Grid data-testid="grid">
29
+ <div>Item</div>
140
30
  </Grid>
141
31
  );
142
- expect(container.firstChild).toHaveClass('gap-8');
32
+ const grid = screen.getByTestId('grid');
33
+ expect(grid).toHaveClass('grid');
143
34
  });
144
35
 
145
- it('should have grid class', () => {
146
- const { container } = render(
147
- <Grid>
148
- <div>Content</div>
36
+ it('renders with custom columns', () => {
37
+ render(
38
+ <Grid cols={3} data-testid="grid">
39
+ <div>Item</div>
149
40
  </Grid>
150
41
  );
151
- expect(container.firstChild).toHaveClass('grid');
42
+ const grid = screen.getByTestId('grid');
43
+ expect(grid).toHaveClass('grid-cols-1', 'lg:grid-cols-3');
152
44
  });
153
45
 
154
- it('should forward ref', () => {
155
- const ref = { current: null };
46
+ it('renders with gap', () => {
156
47
  render(
157
- <Grid ref={ref}>
158
- <div>Content</div>
48
+ <Grid gap="lg" data-testid="grid">
49
+ <div>Item</div>
159
50
  </Grid>
160
51
  );
161
- expect(ref.current).not.toBeNull();
52
+ const grid = screen.getByTestId('grid');
53
+ expect(grid).toHaveClass('gap-6');
162
54
  });
163
55
 
164
- it('should spread additional props', () => {
165
- const { container } = render(
56
+ it('applies default grid styling', () => {
57
+ render(
166
58
  <Grid data-testid="grid">
167
- <div>Content</div>
59
+ <div>Item</div>
168
60
  </Grid>
169
61
  );
170
- expect(container.firstChild).toHaveAttribute('data-testid', 'grid');
62
+ const grid = screen.getByTestId('grid');
63
+ expect(grid).toHaveClass('grid');
171
64
  });
172
65
  });