diff --git a/src/components/PlayerCasoContainer.jsx b/src/components/PlayerCasoContainer.jsx
index 44ffcf7..e8d138c 100644
--- a/src/components/PlayerCasoContainer.jsx
+++ b/src/components/PlayerCasoContainer.jsx
@@ -5,7 +5,6 @@ import ExamService from "../services/ExamService";
import { useHistory } from 'react-router-dom';
import { alertError, alertSuccess } from "../services/AlertService";
import CasoContext from "../context/CasoContext";
-import { CustomButton } from "./custom";
import EnarmUtil from "../modules/EnarmUtil";
import ContributionTypeSelector from "./ContributionTypeSelector";
import ContributionsSummary from "./ContributionsSummary";
diff --git a/src/components/Profile.jsx b/src/components/Profile.jsx
index 70cda21..642ade9 100644
--- a/src/components/Profile.jsx
+++ b/src/components/Profile.jsx
@@ -302,14 +302,17 @@ const Profile = () => {
{categories.map(cat => {
const isSelected = selectedSpecialties.includes(cat.id);
return (
-
- toggleSpecialty(cat.id)}
- />
-
+ toggleSpecialty(cat.id)}
+ s={12}
+ m={6}
+ l={4}
+ style={{ marginBottom: '1rem' }}
+ />
);
})}
diff --git a/src/components/admin/AnswerForm.jsx b/src/components/admin/AnswerForm.jsx
index faa8cce..e99ff50 100644
--- a/src/components/admin/AnswerForm.jsx
+++ b/src/components/admin/AnswerForm.jsx
@@ -25,25 +25,24 @@ const AnswerForm = ({
return (
-
-
- {
- onChangeAnswer(
- questionIndex,
- answerIndex,
- "is_correct",
- event
- );
- }}
- name={answerIsCorrectName}
- value="true"
- />
-
-
+ {
+ onChangeAnswer(
+ questionIndex,
+ answerIndex,
+ "is_correct",
+ event
+ );
+ }}
+ name={answerIsCorrectName}
+ value="true"
+ />
{
const inputRef = useRef(null);
@@ -26,22 +34,70 @@ const CustomCheckbox = ({
inputClasses += ' indeterminate-checkbox';
}
- // The main wrapper is the label for Materialize checkboxes
- return (
-
+ // Construct grid and wrapper classes
+ const hasGrid = s || m || l || xl || offset || wrapperClassName;
+ let finalWrapperClasses = wrapperClassName;
+ if (s) finalWrapperClasses += ` col s${s}`;
+ if (m) finalWrapperClasses += ` col m${m}`;
+ if (l) finalWrapperClasses += ` col l${l}`;
+ if (xl) finalWrapperClasses += ` col xl${xl}`;
+ if (offset) {
+ offset.split(' ').forEach(off => {
+ if (off) finalWrapperClasses += ` offset-${off}`;
+ });
+ }
+
+ const helperTextId = helperText ? `${id}-helper` : undefined;
+
+ const checkboxContent = (
+ <>
+
+ {helperText && {helperText}}
+ >
);
+
+ if (hasGrid) {
+ return (
+
+ {checkboxContent}
+
+ );
+ }
+
+ return checkboxContent;
};
CustomCheckbox.propTypes = {
@@ -54,6 +110,14 @@ CustomCheckbox.propTypes = {
labelClassName: PropTypes.string, // For the label element
indeterminate: PropTypes.bool,
value: PropTypes.string, // HTML value attribute for the checkbox
+ s: PropTypes.number,
+ m: PropTypes.number,
+ l: PropTypes.number,
+ xl: PropTypes.number,
+ offset: PropTypes.string,
+ required: PropTypes.bool,
+ helperText: PropTypes.string,
+ wrapperClassName: PropTypes.string,
};
export default CustomCheckbox;
diff --git a/src/components/custom/CustomCheckbox.test.jsx b/src/components/custom/CustomCheckbox.test.jsx
new file mode 100644
index 0000000..dfc413d
--- /dev/null
+++ b/src/components/custom/CustomCheckbox.test.jsx
@@ -0,0 +1,85 @@
+import { render, screen } from '@testing-library/react';
+import { describe, test, expect } from 'vitest';
+import CustomCheckbox from './CustomCheckbox';
+
+describe('CustomCheckbox', () => {
+ test('renders correctly with label', () => {
+ render();
+ expect(screen.getByLabelText(/Test Label/)).toBeInTheDocument();
+ });
+
+ test('applies grid classes and style to wrapper div', () => {
+ const { container } = render(
+
+ );
+
+ const wrapper = container.firstChild;
+ expect(wrapper.tagName).toBe('DIV');
+ expect(wrapper).toHaveClass('col');
+ expect(wrapper).toHaveClass('s12');
+ expect(wrapper).toHaveClass('m6');
+ expect(wrapper).toHaveClass('offset-s1');
+ expect(wrapper).toHaveStyle('margin-bottom: 16px');
+ expect(wrapper).toHaveAttribute('data-testid', 'outer-wrapper');
+ });
+
+ test('applies style and custom props to label if not wrapped in div', () => {
+ const { container } = render(
+
+ );
+ const label = container.firstChild;
+ expect(label.tagName).toBe('LABEL');
+ expect(label).toHaveStyle('color: red');
+ expect(label).toHaveAttribute('data-custom', 'test');
+ });
+
+ test('renders required indicator and aria-required', () => {
+ render();
+
+ const input = screen.getByLabelText(/Required Label/);
+ expect(input).toHaveAttribute('aria-required', 'true');
+
+ const asterisk = screen.getByTitle('Obligatorio');
+ expect(asterisk).toBeInTheDocument();
+ expect(asterisk).toHaveClass('red-text');
+ expect(asterisk.textContent).toBe('*');
+ });
+
+ test('renders helper text and links with aria-describedby', () => {
+ render();
+
+ const helper = screen.getByText('Be careful');
+ expect(helper).toBeInTheDocument();
+ expect(helper).toHaveClass('helper-text');
+ expect(helper).toHaveAttribute('id', 'help-check-helper');
+
+ const input = screen.getByLabelText(/Help Label/);
+ expect(input).toHaveAttribute('aria-describedby', 'help-check-helper');
+ });
+
+ test('does not wrap in div if no grid or wrapperClassName provided', () => {
+ const { container } = render();
+ expect(container.firstChild.tagName).toBe('LABEL');
+ });
+
+ test('wraps in div if wrapperClassName is provided', () => {
+ const { container } = render(
+
+ );
+ expect(container.firstChild.tagName).toBe('DIV');
+ expect(container.firstChild).toHaveClass('custom-wrap');
+ });
+});