@fabio.caffarello/react-design-system 1.6.0 → 1.7.0

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 (58) hide show
  1. package/dist/index.cjs +29 -4
  2. package/dist/index.js +1866 -716
  3. package/dist/ui/atoms/Button/Button.d.ts +28 -5
  4. package/dist/ui/atoms/Button/Button.stories.d.ts +11 -3
  5. package/dist/ui/atoms/Checkbox/Checkbox.d.ts +24 -0
  6. package/dist/ui/atoms/Checkbox/Checkbox.stories.d.ts +10 -0
  7. package/dist/ui/atoms/Checkbox/Checkbox.test.d.ts +1 -0
  8. package/dist/ui/atoms/Collapsible/Collapsible.d.ts +29 -0
  9. package/dist/ui/atoms/Collapsible/Collapsible.stories.d.ts +9 -0
  10. package/dist/ui/atoms/Collapsible/Collapsible.test.d.ts +1 -0
  11. package/dist/ui/atoms/Input/Input.d.ts +28 -4
  12. package/dist/ui/atoms/Input/Input.stories.d.ts +8 -3
  13. package/dist/ui/atoms/Radio/Radio.d.ts +26 -0
  14. package/dist/ui/atoms/Radio/Radio.stories.d.ts +10 -0
  15. package/dist/ui/atoms/Radio/Radio.test.d.ts +1 -0
  16. package/dist/ui/atoms/SidebarItem/SidebarItem.d.ts +3 -1
  17. package/dist/ui/atoms/SidebarItem/SidebarItem.stories.d.ts +3 -0
  18. package/dist/ui/atoms/index.d.ts +7 -0
  19. package/dist/ui/hooks/useCollapsible.d.ts +27 -0
  20. package/dist/ui/index.d.ts +13 -0
  21. package/dist/ui/molecules/InputWithLabel/InputWithLabel.d.ts +4 -2
  22. package/dist/ui/molecules/SidebarGroup/SidebarGroup.d.ts +8 -1
  23. package/dist/ui/molecules/SidebarGroup/SidebarGroup.stories.d.ts +11 -0
  24. package/dist/ui/molecules/SidebarGroup/SidebarGroup.test.d.ts +1 -0
  25. package/dist/ui/providers/ThemeProvider.d.ts +34 -0
  26. package/dist/ui/tokens/breakpoints.d.ts +36 -0
  27. package/dist/ui/tokens/colors.d.ts +89 -0
  28. package/dist/ui/tokens/sidebar.d.ts +48 -0
  29. package/dist/ui/tokens/spacing.d.ts +53 -0
  30. package/dist/ui/tokens/themes/dark.d.ts +38 -0
  31. package/dist/ui/tokens/themes/light.d.ts +38 -0
  32. package/dist/ui/tokens/tokens.factory.d.ts +57 -0
  33. package/dist/ui/tokens/typography.d.ts +90 -0
  34. package/package.json +3 -2
  35. package/src/ui/atoms/Button/Button.stories.tsx +77 -7
  36. package/src/ui/atoms/Button/Button.tsx +176 -28
  37. package/src/ui/atoms/Checkbox/Checkbox.stories.tsx +61 -0
  38. package/src/ui/atoms/Checkbox/Checkbox.test.tsx +32 -0
  39. package/src/ui/atoms/Checkbox/Checkbox.tsx +103 -0
  40. package/src/ui/atoms/Collapsible/Collapsible.tsx +2 -2
  41. package/src/ui/atoms/Input/Input.stories.tsx +67 -6
  42. package/src/ui/atoms/Input/Input.tsx +117 -14
  43. package/src/ui/atoms/Radio/Radio.stories.tsx +72 -0
  44. package/src/ui/atoms/Radio/Radio.test.tsx +32 -0
  45. package/src/ui/atoms/Radio/Radio.tsx +104 -0
  46. package/src/ui/atoms/index.ts +7 -0
  47. package/src/ui/index.ts +14 -0
  48. package/src/ui/molecules/InputWithLabel/InputWithLabel.tsx +5 -4
  49. package/src/ui/molecules/SidebarGroup/SidebarGroup.tsx +30 -38
  50. package/src/ui/providers/ThemeProvider.tsx +105 -0
  51. package/src/ui/tokens/breakpoints.ts +71 -0
  52. package/src/ui/tokens/colors.ts +250 -0
  53. package/src/ui/tokens/sidebar.ts +9 -3
  54. package/src/ui/tokens/spacing.ts +127 -0
  55. package/src/ui/tokens/themes/dark.ts +18 -0
  56. package/src/ui/tokens/themes/light.ts +18 -0
  57. package/src/ui/tokens/tokens.factory.ts +117 -0
  58. package/src/ui/tokens/typography.ts +191 -0
@@ -0,0 +1,103 @@
1
+ 'use client';
2
+
3
+ import type { InputHTMLAttributes, ReactNode } from 'react';
4
+ import { getTypographyClasses } from '../../tokens/typography';
5
+
6
+ export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {
7
+ label?: ReactNode;
8
+ error?: boolean;
9
+ helperText?: string;
10
+ }
11
+
12
+ /**
13
+ * Checkbox Component
14
+ *
15
+ * A styled checkbox input component.
16
+ * Follows Atomic Design principles as an Atom component.
17
+ * Uses Composite Pattern when combined with Label and ErrorMessage.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * <Checkbox
22
+ * id="terms"
23
+ * label="I agree to the terms"
24
+ * checked={checked}
25
+ * onChange={handleChange}
26
+ * />
27
+ * ```
28
+ */
29
+ export default function Checkbox({
30
+ id,
31
+ label,
32
+ error = false,
33
+ helperText,
34
+ className = '',
35
+ disabled = false,
36
+ ...props
37
+ }: CheckboxProps) {
38
+ const checkboxId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
39
+ const errorId = error ? `${checkboxId}-error` : undefined;
40
+ const helperId = helperText ? `${checkboxId}-helper` : undefined;
41
+
42
+ const baseClasses = [
43
+ 'h-4',
44
+ 'w-4',
45
+ 'rounded',
46
+ 'border-gray-300',
47
+ 'text-indigo-600',
48
+ 'focus:ring-2',
49
+ 'focus:ring-indigo-500',
50
+ 'focus:ring-offset-2',
51
+ 'disabled:opacity-50',
52
+ 'disabled:cursor-not-allowed',
53
+ 'cursor-pointer',
54
+ ];
55
+
56
+ const errorClasses = error
57
+ ? 'border-red-500 focus:ring-red-500'
58
+ : '';
59
+
60
+ const checkboxClasses = [
61
+ ...baseClasses,
62
+ errorClasses,
63
+ ].filter(Boolean).join(' ');
64
+
65
+ const labelClasses = [
66
+ getTypographyClasses('label'),
67
+ 'ml-2',
68
+ disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer',
69
+ ].filter(Boolean).join(' ');
70
+
71
+ return (
72
+ <div className={`flex flex-col my-2 ${className}`}>
73
+ <div className="flex items-center">
74
+ <input
75
+ type="checkbox"
76
+ id={checkboxId}
77
+ className={checkboxClasses}
78
+ disabled={disabled}
79
+ aria-invalid={error}
80
+ aria-describedby={errorId || helperId}
81
+ {...props}
82
+ />
83
+ {label && (
84
+ <label
85
+ htmlFor={checkboxId}
86
+ className={labelClasses}
87
+ >
88
+ {label}
89
+ </label>
90
+ )}
91
+ </div>
92
+ {(error || helperText) && (
93
+ <div
94
+ id={errorId || helperId}
95
+ className={`mt-1 ${getTypographyClasses('caption')} ${error ? 'text-red-600' : 'text-gray-500'}`}
96
+ role={error ? 'alert' : undefined}
97
+ >
98
+ {error || helperText}
99
+ </div>
100
+ )}
101
+ </div>
102
+ );
103
+ }
@@ -43,7 +43,7 @@ export default function Collapsible({
43
43
  className = '',
44
44
  ...props
45
45
  }: CollapsibleProps) {
46
- const { isOpen, toggle, setOpen } = useCollapsible({
46
+ const { isOpen, toggle } = useCollapsible({
47
47
  defaultOpen,
48
48
  open,
49
49
  onOpenChange,
@@ -94,7 +94,7 @@ export default function Collapsible({
94
94
  aria-expanded={isOpen}
95
95
  aria-controls={contentId}
96
96
  aria-disabled={disabled}
97
- className="w-full text-left"
97
+ className="w-full text-left focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 rounded-md"
98
98
  >
99
99
  {trigger}
100
100
  </button>
@@ -1,15 +1,76 @@
1
- import type { Meta, StoryObj } from "@storybook/react";
2
- import Input from "./Input";
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import Input from './Input';
3
3
 
4
4
  const meta: Meta<typeof Input> = {
5
- title: "UI/Atoms/Input",
5
+ title: 'Atoms/Input',
6
6
  component: Input,
7
+ tags: ['autodocs'],
8
+ argTypes: {
9
+ label: {
10
+ control: 'text',
11
+ },
12
+ error: {
13
+ control: 'boolean',
14
+ },
15
+ size: {
16
+ control: 'select',
17
+ options: ['sm', 'md', 'lg'],
18
+ },
19
+ variant: {
20
+ control: 'select',
21
+ options: ['default', 'outlined', 'filled'],
22
+ },
23
+ disabled: {
24
+ control: 'boolean',
25
+ },
26
+ },
7
27
  };
8
28
 
9
- export const Primary: StoryObj<typeof Input> = {
29
+ export default meta;
30
+ type Story = StoryObj<typeof Input>;
31
+
32
+ export const Default: Story = {
10
33
  args: {
11
- placeholder: "Hello from Storybook",
34
+ label: 'Email',
35
+ type: 'email',
36
+ placeholder: 'Enter your email',
12
37
  },
13
38
  };
14
39
 
15
- export default meta;
40
+ export const WithError: Story = {
41
+ args: {
42
+ label: 'Email',
43
+ type: 'email',
44
+ placeholder: 'Enter your email',
45
+ error: true,
46
+ helperText: 'Please enter a valid email address',
47
+ },
48
+ };
49
+
50
+ export const Sizes: Story = {
51
+ render: () => (
52
+ <div className="space-y-4">
53
+ <Input label="Small" size="sm" placeholder="Small input" />
54
+ <Input label="Medium" size="md" placeholder="Medium input" />
55
+ <Input label="Large" size="lg" placeholder="Large input" />
56
+ </div>
57
+ ),
58
+ };
59
+
60
+ export const Variants: Story = {
61
+ render: () => (
62
+ <div className="space-y-4">
63
+ <Input label="Default" variant="default" placeholder="Default variant" />
64
+ <Input label="Outlined" variant="outlined" placeholder="Outlined variant" />
65
+ <Input label="Filled" variant="filled" placeholder="Filled variant" />
66
+ </div>
67
+ ),
68
+ };
69
+
70
+ export const Disabled: Story = {
71
+ args: {
72
+ label: 'Disabled Input',
73
+ placeholder: 'This input is disabled',
74
+ disabled: true,
75
+ },
76
+ };
@@ -1,19 +1,122 @@
1
- import type { HTMLProps } from "react";
1
+ 'use client';
2
2
 
3
- type Props = HTMLProps<HTMLInputElement>;
3
+ import type { InputHTMLAttributes, ReactNode } from 'react';
4
+ import { getTypographyClasses } from '../../tokens/typography';
5
+ import { getColorClass } from '../../tokens/colors';
4
6
 
5
- export default function Input({ className, ...props }: Props) {
6
- const classNames = [
7
- className,
8
- "px-large",
9
- "border",
10
- "border-1",
11
- "border-grey-light",
12
- "rounded",
13
- "lh-form-element",
14
- "h-form-element",
15
- "text-base",
7
+ export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
8
+ label?: ReactNode;
9
+ error?: boolean;
10
+ helperText?: string;
11
+ size?: 'sm' | 'md' | 'lg';
12
+ variant?: 'default' | 'outlined' | 'filled';
13
+ }
14
+
15
+ /**
16
+ * Input Component
17
+ *
18
+ * A styled text input component with label and error support.
19
+ * Follows Atomic Design principles as an Atom component.
20
+ * Uses Composite Pattern when combined with Label and ErrorMessage.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <Input
25
+ * id="email"
26
+ * label="Email"
27
+ * type="email"
28
+ * placeholder="Enter your email"
29
+ * error={hasError}
30
+ * helperText={errorMessage}
31
+ * />
32
+ * ```
33
+ */
34
+ export default function Input({
35
+ id,
36
+ label,
37
+ error = false,
38
+ helperText,
39
+ size = 'md',
40
+ variant = 'outlined',
41
+ className = '',
42
+ disabled = false,
43
+ ...props
44
+ }: InputProps) {
45
+ const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`;
46
+ const errorId = error ? `${inputId}-error` : undefined;
47
+ const helperId = helperText ? `${inputId}-helper` : undefined;
48
+
49
+ // Size classes
50
+ const sizeClasses = {
51
+ sm: 'h-8 text-sm px-3',
52
+ md: 'h-10 text-base px-4',
53
+ lg: 'h-12 text-lg px-5',
54
+ };
55
+
56
+ // Variant classes
57
+ const variantClasses = {
58
+ default: 'border-0 border-b-2 border-gray-300 focus:border-indigo-500',
59
+ outlined: 'border border-gray-300 focus:border-indigo-500',
60
+ filled: 'bg-gray-100 border-0 focus:bg-white focus:ring-2 focus:ring-indigo-500',
61
+ };
62
+
63
+ const baseClasses = [
64
+ 'w-full',
65
+ 'rounded-md',
66
+ 'transition-colors',
67
+ 'focus:outline-none',
68
+ 'focus:ring-2',
69
+ 'focus:ring-offset-2',
70
+ 'disabled:opacity-50',
71
+ 'disabled:cursor-not-allowed',
72
+ sizeClasses[size],
73
+ variantClasses[variant],
16
74
  ];
17
75
 
18
- return <input className={classNames.join(" ")} {...props} />;
76
+ const errorClasses = error
77
+ ? 'border-red-500 focus:border-red-500 focus:ring-red-500'
78
+ : '';
79
+
80
+ const inputClasses = [
81
+ ...baseClasses,
82
+ errorClasses,
83
+ className,
84
+ ].filter(Boolean).join(' ');
85
+
86
+ const labelClasses = [
87
+ 'block',
88
+ getTypographyClasses('label'),
89
+ 'mb-1',
90
+ disabled ? 'opacity-50' : '',
91
+ ].filter(Boolean).join(' ');
92
+
93
+ return (
94
+ <div className="w-full">
95
+ {label && (
96
+ <label
97
+ htmlFor={inputId}
98
+ className={labelClasses}
99
+ >
100
+ {label}
101
+ </label>
102
+ )}
103
+ <input
104
+ id={inputId}
105
+ className={inputClasses}
106
+ disabled={disabled}
107
+ aria-invalid={error}
108
+ aria-describedby={errorId || helperId}
109
+ {...props}
110
+ />
111
+ {(error || helperText) && (
112
+ <div
113
+ id={errorId || helperId}
114
+ className={`mt-1 ${getTypographyClasses('caption')} ${error ? getColorClass('error', 'DEFAULT', 'text') : 'text-gray-500'}`}
115
+ role={error ? 'alert' : undefined}
116
+ >
117
+ {error || helperText}
118
+ </div>
119
+ )}
120
+ </div>
121
+ );
19
122
  }
@@ -0,0 +1,72 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import Radio from './Radio';
3
+
4
+ const meta: Meta<typeof Radio> = {
5
+ title: 'Atoms/Radio',
6
+ component: Radio,
7
+ tags: ['autodocs'],
8
+ argTypes: {
9
+ label: {
10
+ control: 'text',
11
+ },
12
+ error: {
13
+ control: 'boolean',
14
+ },
15
+ disabled: {
16
+ control: 'boolean',
17
+ },
18
+ checked: {
19
+ control: 'boolean',
20
+ },
21
+ },
22
+ };
23
+
24
+ export default meta;
25
+ type Story = StoryObj<typeof Radio>;
26
+
27
+ export const Default: Story = {
28
+ args: {
29
+ name: 'option',
30
+ label: 'Option 1',
31
+ value: '1',
32
+ checked: false,
33
+ },
34
+ };
35
+
36
+ export const Checked: Story = {
37
+ args: {
38
+ name: 'option',
39
+ label: 'Selected option',
40
+ value: '1',
41
+ checked: true,
42
+ },
43
+ };
44
+
45
+ export const WithError: Story = {
46
+ args: {
47
+ name: 'option',
48
+ label: 'Option with error',
49
+ value: '1',
50
+ error: true,
51
+ helperText: 'Please select an option',
52
+ },
53
+ };
54
+
55
+ export const Disabled: Story = {
56
+ args: {
57
+ name: 'option',
58
+ label: 'Disabled option',
59
+ value: '1',
60
+ disabled: true,
61
+ },
62
+ };
63
+
64
+ export const RadioGroup: Story = {
65
+ render: () => (
66
+ <div className="space-y-2">
67
+ <Radio name="group" label="Option 1" value="1" />
68
+ <Radio name="group" label="Option 2" value="2" checked />
69
+ <Radio name="group" label="Option 3" value="3" />
70
+ </div>
71
+ ),
72
+ };
@@ -0,0 +1,32 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { vi } from 'vitest';
4
+ import Radio from './Radio';
5
+
6
+ describe('Radio', () => {
7
+ it('renders radio with label', () => {
8
+ render(<Radio name="test" label="Test radio" value="test" />);
9
+ expect(screen.getByLabelText('Test radio')).toBeInTheDocument();
10
+ });
11
+
12
+ it('handles click events', async () => {
13
+ const handleChange = vi.fn();
14
+ render(<Radio name="test" label="Test" value="test" onChange={handleChange} />);
15
+
16
+ const radio = screen.getByLabelText('Test');
17
+ await userEvent.click(radio);
18
+
19
+ expect(handleChange).toHaveBeenCalledTimes(1);
20
+ });
21
+
22
+ it('shows error state', () => {
23
+ render(<Radio name="test" label="Test" value="test" error helperText="Error message" />);
24
+ expect(screen.getByText('Error message')).toBeInTheDocument();
25
+ expect(screen.getByRole('radio')).toHaveAttribute('aria-invalid', 'true');
26
+ });
27
+
28
+ it('is disabled when disabled prop is true', () => {
29
+ render(<Radio name="test" label="Test" value="test" disabled />);
30
+ expect(screen.getByRole('radio')).toBeDisabled();
31
+ });
32
+ });
@@ -0,0 +1,104 @@
1
+ 'use client';
2
+
3
+ import type { InputHTMLAttributes, ReactNode } from 'react';
4
+ import { getTypographyClasses } from '../../tokens/typography';
5
+
6
+ export interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {
7
+ label?: ReactNode;
8
+ error?: boolean;
9
+ helperText?: string;
10
+ }
11
+
12
+ /**
13
+ * Radio Component
14
+ *
15
+ * A styled radio input component.
16
+ * Follows Atomic Design principles as an Atom component.
17
+ * Uses Composite Pattern when combined with Label and ErrorMessage.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * <Radio
22
+ * id="option1"
23
+ * name="options"
24
+ * label="Option 1"
25
+ * value="1"
26
+ * checked={selected === "1"}
27
+ * onChange={handleChange}
28
+ * />
29
+ * ```
30
+ */
31
+ export default function Radio({
32
+ id,
33
+ label,
34
+ error = false,
35
+ helperText,
36
+ className = '',
37
+ disabled = false,
38
+ ...props
39
+ }: RadioProps) {
40
+ const radioId = id || `radio-${Math.random().toString(36).substr(2, 9)}`;
41
+ const errorId = error ? `${radioId}-error` : undefined;
42
+ const helperId = helperText ? `${radioId}-helper` : undefined;
43
+
44
+ const baseClasses = [
45
+ 'h-4',
46
+ 'w-4',
47
+ 'border-gray-300',
48
+ 'text-indigo-600',
49
+ 'focus:ring-2',
50
+ 'focus:ring-indigo-500',
51
+ 'focus:ring-offset-2',
52
+ 'disabled:opacity-50',
53
+ 'disabled:cursor-not-allowed',
54
+ 'cursor-pointer',
55
+ ];
56
+
57
+ const errorClasses = error
58
+ ? 'border-red-500 focus:ring-red-500'
59
+ : '';
60
+
61
+ const radioClasses = [
62
+ ...baseClasses,
63
+ errorClasses,
64
+ ].filter(Boolean).join(' ');
65
+
66
+ const labelClasses = [
67
+ getTypographyClasses('label'),
68
+ 'ml-2',
69
+ disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer',
70
+ ].filter(Boolean).join(' ');
71
+
72
+ return (
73
+ <div className={`flex flex-col my-2 ${className}`}>
74
+ <div className="flex items-center">
75
+ <input
76
+ type="radio"
77
+ id={radioId}
78
+ className={radioClasses}
79
+ disabled={disabled}
80
+ aria-invalid={error}
81
+ aria-describedby={errorId || helperId}
82
+ {...props}
83
+ />
84
+ {label && (
85
+ <label
86
+ htmlFor={radioId}
87
+ className={labelClasses}
88
+ >
89
+ {label}
90
+ </label>
91
+ )}
92
+ </div>
93
+ {(error || helperText) && (
94
+ <div
95
+ id={errorId || helperId}
96
+ className={`mt-1 ${getTypographyClasses('caption')} ${error ? 'text-red-600' : 'text-gray-500'}`}
97
+ role={error ? 'alert' : undefined}
98
+ >
99
+ {error || helperText}
100
+ </div>
101
+ )}
102
+ </div>
103
+ );
104
+ }
@@ -3,6 +3,7 @@ export { default as Info } from "./Info/Info";
3
3
  export { default as Text } from "./Text/Text";
4
4
 
5
5
  export { default as Input } from "./Input/Input";
6
+ export type { InputProps } from "./Input/Input";
6
7
 
7
8
  export { default as Button } from "./Button/Button";
8
9
 
@@ -31,3 +32,9 @@ export type { SidebarItemProps } from "./SidebarItem/SidebarItem";
31
32
 
32
33
  export { default as Collapsible } from "./Collapsible/Collapsible";
33
34
  export type { CollapsibleProps } from "./Collapsible/Collapsible";
35
+
36
+ export { default as Checkbox } from "./Checkbox/Checkbox";
37
+ export type { CheckboxProps } from "./Checkbox/Checkbox";
38
+
39
+ export { default as Radio } from "./Radio/Radio";
40
+ export type { RadioProps } from "./Radio/Radio";
package/src/ui/index.ts CHANGED
@@ -2,3 +2,17 @@ export * from "./atoms";
2
2
  export * from "./molecules";
3
3
  export * from "./organisms";
4
4
  export * from "./tokens/sidebar";
5
+ export * from "./tokens/spacing";
6
+ export * from "./tokens/typography";
7
+ export * from "./tokens/colors";
8
+ export * from "./tokens/breakpoints";
9
+ export * from "./tokens/tokens.factory";
10
+ export * from "./tokens/themes/light";
11
+ export * from "./tokens/themes/dark";
12
+ export * from "./providers/ThemeProvider";
13
+
14
+ // Export helper functions for convenience
15
+ export { getSpacingClass, getSpacing } from "./tokens/spacing";
16
+ export { getTypographyClasses, getTypography } from "./tokens/typography";
17
+ export { getColorClass, getColor } from "./tokens/colors";
18
+ export { getBreakpoint, getMediaQuery } from "./tokens/breakpoints";
@@ -1,11 +1,12 @@
1
1
  import type { HTMLProps } from "react";
2
- import { Text, Input } from "../../atoms";
2
+ import { Text, Input, type InputProps } from "../../atoms";
3
3
 
4
- interface Props extends HTMLProps<HTMLInputElement> {
4
+ interface Props extends Omit<HTMLProps<HTMLInputElement>, 'size'> {
5
5
  label: string;
6
+ size?: InputProps['size'];
6
7
  }
7
8
 
8
- export default function InputWithLabel({ label, ...props }: Props) {
9
+ export default function InputWithLabel({ label, size, ...props }: Props) {
9
10
  if (!props.id) {
10
11
  console.error("InputWithLabel component requires an id prop");
11
12
  }
@@ -15,7 +16,7 @@ export default function InputWithLabel({ label, ...props }: Props) {
15
16
  <Text as="label" htmlFor={props.id} className="cursor-pointer">
16
17
  {label}
17
18
  </Text>
18
- <Input {...props} />
19
+ <Input {...props} size={size} />
19
20
  </div>
20
21
  );
21
22
  }