Skip to content

Commit 115eabe

Browse files
committed
reverting the last 3 commits
1 parent 0dcd468 commit 115eabe

27 files changed

+1095
-621
lines changed

src/components/ui/Radio/Radio.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use client';
2+
import React from 'react';
3+
import RadioPrimitive, { RadioPrimitiveProps } from '~/core/primitives/Radio';
4+
5+
import clsx from 'clsx';
6+
import { customClassSwitcher } from '~/core';
7+
8+
import { useCreateDataAttribute, useComposeAttributes, useCreateDataAccentColorAttribute } from '~/core/hooks/createDataAttribute';
9+
10+
const COMPONENT_NAME = 'Radio';
11+
12+
export type RadioProps = RadioPrimitiveProps & {
13+
customRootClass?: string;
14+
className?: string;
15+
size?: string;
16+
color?: string;
17+
variant?: string;
18+
};
19+
20+
function Radio({ name, value, id, checked = false, required, onChange, disabled, asChild, className, customRootClass, variant = '', size = '', color = '', ...props }: RadioProps) {
21+
const rootClass = customClassSwitcher(customRootClass, COMPONENT_NAME);
22+
const [isChecked, setIsChecked] = React.useState(checked);
23+
24+
const dataAttributes = useCreateDataAttribute('button', { variant, size });
25+
const accentAttributes = useCreateDataAccentColorAttribute(color);
26+
const composedAttributes = useComposeAttributes(dataAttributes(), accentAttributes());
27+
28+
const handleChange = () => {
29+
if (onChange) {
30+
onChange();
31+
}
32+
setIsChecked(!isChecked);
33+
};
34+
return (
35+
<RadioPrimitive
36+
name={name}
37+
id={id}
38+
value={value}
39+
checked={isChecked}
40+
required={required}
41+
onChange={handleChange}
42+
disabled={disabled}
43+
asChild={asChild}
44+
className={clsx(rootClass, className)}
45+
data-checked={isChecked}
46+
{...composedAttributes()}
47+
{...props}
48+
/>
49+
50+
);
51+
}
52+
53+
export default Radio;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React from 'react';
2+
import Radio from '../Radio';
3+
import SandboxEditor from '~/components/tools/SandboxEditor/SandboxEditor';
4+
5+
export default {
6+
title: 'WIP/Radio',
7+
component: Radio,
8+
render: (args: React.ComponentProps<typeof Radio>) => (
9+
<SandboxEditor>
10+
<form>
11+
<Radio {...args} />
12+
<label htmlFor={args.id || 'radio'} style={{ marginLeft: 8 }}>
13+
Radio 1
14+
</label>
15+
</form>
16+
</SandboxEditor>
17+
)
18+
};
19+
20+
export const Default = {
21+
args: {
22+
name: 'radio',
23+
value: 'radio',
24+
id: 'radio',
25+
required: true,
26+
onChange: () => {
27+
// action handler
28+
}
29+
}
30+
};
31+
32+
export const Disabled = {
33+
args: {
34+
disabled: true,
35+
name: 'radio',
36+
value: 'radio1',
37+
id: 'radio1',
38+
onChange: () => {
39+
// action handler
40+
}
41+
}
42+
};
43+
44+
export const Variants = {
45+
render: (args: React.ComponentProps<typeof Radio>) => (
46+
<SandboxEditor>
47+
<div style={{ display: 'flex', gap: 16 }}>
48+
<div>
49+
<Radio {...args} variant="outline" id="radio-outline" />
50+
<label htmlFor="radio-outline" style={{ marginLeft: 8 }}>Outline</label>
51+
</div>
52+
<div>
53+
<Radio {...args} variant="solid" id="radio-solid" />
54+
<label htmlFor="radio-solid" style={{ marginLeft: 8 }}>Solid</label>
55+
</div>
56+
</div>
57+
</SandboxEditor>
58+
),
59+
args: {
60+
name: 'radio-variant',
61+
value: 'radio',
62+
required: false,
63+
onChange: () => {}
64+
}
65+
};
66+
67+
export const Sizes = {
68+
render: (args: React.ComponentProps<typeof Radio>) => (
69+
<SandboxEditor>
70+
<div style={{ display: 'flex', gap: 16 }}>
71+
<div>
72+
<Radio {...args} size="small" id="radio-small" />
73+
<label htmlFor="radio-small" style={{ marginLeft: 8 }}>Small</label>
74+
</div>
75+
<div>
76+
<Radio {...args} size="medium" id="radio-medium" />
77+
<label htmlFor="radio-medium" style={{ marginLeft: 8 }}>Medium</label>
78+
</div>
79+
<div>
80+
<Radio {...args} size="large" id="radio-large" />
81+
<label htmlFor="radio-large" style={{ marginLeft: 8 }}>Large</label>
82+
</div>
83+
</div>
84+
</SandboxEditor>
85+
),
86+
args: {
87+
name: 'radio-size',
88+
value: 'radio',
89+
required: false,
90+
onChange: () => {}
91+
}
92+
};
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from 'react';
2+
import { render, screen, fireEvent } from '@testing-library/react';
3+
import Radio from '../Radio';
4+
5+
describe('Radio', () => {
6+
const baseProps = {
7+
name: 'test-radio',
8+
value: 'option1',
9+
id: 'radio1'
10+
};
11+
12+
it('renders with required props', () => {
13+
render(<Radio {...baseProps} />);
14+
const radio = screen.getByRole('radio');
15+
expect(radio).toBeInTheDocument();
16+
expect(radio).toHaveAttribute('name', 'test-radio');
17+
expect(radio).toHaveAttribute('value', 'option1');
18+
expect(radio).toHaveAttribute('id', 'radio1');
19+
});
20+
21+
it('applies checked, required, and disabled props', () => {
22+
render(
23+
<Radio {...baseProps} checked required disabled />
24+
);
25+
const radio = screen.getByRole('radio');
26+
expect(radio).toBeChecked();
27+
expect(radio).toBeRequired();
28+
expect(radio).toBeDisabled();
29+
expect(radio).toHaveAttribute('aria-disabled', 'true');
30+
expect(radio).toHaveAttribute('aria-required', 'true');
31+
});
32+
33+
it('toggles checked state on click', () => {
34+
render(<Radio {...baseProps} />);
35+
const radio = screen.getByRole('radio');
36+
expect(radio).not.toBeChecked();
37+
fireEvent.click(radio);
38+
expect(radio).toBeChecked();
39+
});
40+
41+
it('calls onChange when clicked', () => {
42+
const handleChange = jest.fn();
43+
render(
44+
<Radio {...baseProps} onChange={handleChange} />
45+
);
46+
const radio = screen.getByRole('radio');
47+
fireEvent.click(radio);
48+
expect(handleChange).toHaveBeenCalled();
49+
});
50+
51+
it('applies custom class names', () => {
52+
render(
53+
<Radio {...baseProps} className="custom-class" customRootClass="root-class" />
54+
);
55+
const radio = screen.getByRole('radio');
56+
expect(radio.className).toMatch(/custom-class/);
57+
expect(radio.className).toMatch(/root-class/);
58+
});
59+
60+
it('applies data attributes for variant, size, and color', () => {
61+
render(
62+
<Radio {...baseProps} variant="filled" size="lg" color="red" />
63+
);
64+
const radio = screen.getByRole('radio');
65+
expect(radio).toHaveAttribute('data-button-variant', 'filled');
66+
expect(radio).toHaveAttribute('data-button-size', 'lg');
67+
expect(radio).toHaveAttribute('data-rad-ui-accent-color', 'red');
68+
});
69+
});

src/components/ui/TabNav/fragments/TabNavLink.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ const TabNavLink = ({ value, className = '', href = '#', children, disabled, asC
3939
asChild={asChild}
4040
aria-disabled={disabled}
4141
aria-selected={isActive}
42-
// @ts-expect-error
4342
disabled={disabled}
4443
{...disabled ? {} : { href }}
4544
>

src/core/primitives/Dialog/fragments/DialogPrimitiveRoot.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export type DialogPrimitiveRootProps = {
1313

1414
const COMPONENT_NAME = 'DialogPrimitive';
1515

16-
const DialogPrimitiveRoot = ({ children, open=false, onOpenChange = () => {}, onClickOutside = () => {}, className, ...props } : DialogPrimitiveRootProps) => {
16+
const DialogPrimitiveRoot = ({ children, open = false, onOpenChange = () => {}, onClickOutside = () => {}, className, ...props } : DialogPrimitiveRootProps) => {
1717
const [isOpen, setIsOpen] = useState(open);
1818
const handleOpenChange = (open: boolean) => {
1919
setIsOpen(open);

src/core/primitives/Primitive/index.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ const SUPPORTED_HTML_ELEMENTS = ['div', 'span', 'button', 'input', 'a', 'img', '
55
type SupportedElement = typeof SUPPORTED_HTML_ELEMENTS[number];
66

77
// Update type definitions to be more specific
8-
interface PrimitiveProps extends React.HTMLAttributes<HTMLElement> {
9-
asChild?: boolean;
10-
children?: React.ReactNode;
11-
}
8+
type PrimitiveProps =
9+
| (React.InputHTMLAttributes<HTMLInputElement> & { asChild?: boolean })
10+
| (React.HTMLAttributes<HTMLElement> & { asChild?: boolean, children?: React.ReactNode });
1211

1312
// Update component creation with proper typing
1413
const createPrimitiveComponent = (elementType: SupportedElement) => {

src/core/primitives/Radio/RadioPrimitive.stories.tsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ export default {
88
render: (args:React.ComponentProps<typeof RadioPrimitive>) => <SandboxEditor>
99

1010
<div className='flex flex-col gap-2'>
11+
1112
<span>
12-
<RadioPrimitive name='radio' value='radio' checked={true} />
13-
<label htmlFor='radio'>Radio 1</label>
14-
</span>
15-
<span>
16-
<RadioPrimitive name='radio' value='radio2'/>
17-
<label htmlFor='radio2'>Radio 2</label>
13+
<form>
14+
<RadioPrimitive {...args}/>
15+
<label htmlFor='radio'>Radio 1</label>
16+
</form>
1817
</span>
1918
</div>
2019
</SandboxEditor>
@@ -23,8 +22,24 @@ export default {
2322

2423
export const All = {
2524
args: {
25+
onClick: (data: any) => {
26+
console.log('data', data);
27+
},
28+
name: 'radio',
29+
value: 'radio',
30+
id: 'radio',
31+
required: true
32+
}
33+
};
34+
35+
export const Disabled = {
36+
args: {
37+
disabled: true,
38+
name: 'radio',
39+
value: 'radio1',
2640
onClick: (data: any) => {
2741
console.log('data', data);
2842
}
43+
2944
}
3045
};
Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
1-
import React, { useState } from 'react';
2-
import Primitive from '~/core/primitives/Primitive';
1+
import React from 'react';
2+
import Primitive from '../Primitive';
33

44
export type RadioPrimitiveProps = {
5-
onClick?: (data: any) => void;
6-
onChange?: (data: any) => void;
7-
checked?: boolean;
85
name: string;
96
value: string;
10-
};
11-
12-
const RadioPrimitive = ({ name = '', value = '', checked = false, onClick, onChange, ...props }:RadioPrimitiveProps) => {
13-
const [isChecked, setIsChecked] = useState(checked);
14-
const dataAttributes = {
15-
'data-checked': isChecked.toString()
16-
};
17-
18-
const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
19-
const isChecked = event.target.checked;
20-
console.log(isChecked);
21-
if (typeof onChange === 'function') {
22-
setIsChecked(isChecked);
23-
onChange({
24-
value,
25-
checked: isChecked
26-
});
27-
}
28-
};
7+
id: string;
8+
onChange?: () => void;
9+
checked?: boolean;
10+
required?: boolean;
11+
disabled?: boolean;
12+
asChild?: boolean;
13+
className?: string;
14+
}
2915

16+
function RadioPrimitive({ name, value, id, checked, required, onChange, disabled, asChild, className, ...props }: RadioPrimitiveProps) {
3017
return (
31-
<Primitive.input id={value} type='radio' value={value} name={name} onChange={handleOnChange} {...props} {...dataAttributes}/>
18+
<Primitive.input
19+
type="radio"
20+
checked={checked}
21+
name={name}
22+
tabIndex={-1}
23+
value={value}
24+
onChange={onChange}
25+
id={id}
26+
aria-disabled={disabled}
27+
disabled={disabled}
28+
required={required}
29+
aria-required={required}
30+
asChild={asChild}
31+
className={className}
32+
{...props}
33+
/>
3234
);
33-
};
35+
}
3436

3537
export default RadioPrimitive;

0 commit comments

Comments
 (0)