Skip to content

Commit b6d2318

Browse files
committed
feat(form): Added props to style Checkbox and Radio input element
1 parent 437af72 commit b6d2318

File tree

3 files changed

+118
-1
lines changed

3 files changed

+118
-1
lines changed

packages/form/src/toggle/InputToggle.tsx

+35-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,37 @@ export interface InputToggleProps
6464
*/
6565
toggleClassName?: string;
6666

67+
/**
68+
* An optional `style` to provide to the invisible `<input>` element that is
69+
* used to toggle the checked state. This prop is only available since the
70+
* `style` prop is passed to the container element, but you probably shouldn't
71+
* really style this element anyways.
72+
*
73+
* @since 2.2.0
74+
*/
75+
inputStyle?: CSSProperties;
76+
77+
/**
78+
* An optional `className` to provide to the invisible `<input>` element that
79+
* is used to toggle the checked state. This prop does not have many uses and
80+
* is really just provided since the `className` is passed to the container
81+
* element instead of the `<input>`. However, this can be used to update the
82+
* icon styles if needed using the `:checked` state:
83+
*
84+
* ```scss
85+
* .custom-toggle-icon {
86+
* // styles
87+
* }
88+
*
89+
* .custom-input:checked + .custom-toggle-icon {
90+
* // custom checked styles
91+
* }
92+
* ```
93+
*
94+
* @since 2.2.0
95+
*/
96+
inputClassName?: string;
97+
6798
/**
6899
* Boolean if the icon's overlay should be disabled. The way the Checkbox and
69100
* Radio input elements work is by applying different opacity to the
@@ -148,6 +179,8 @@ const InputToggle = forwardRef<HTMLInputElement, Props>(function InputToggle(
148179
iconClassName,
149180
toggleStyle,
150181
toggleClassName: propToggleClassName,
182+
inputStyle,
183+
inputClassName,
151184
icon,
152185
onFocus: propOnFocus,
153186
onBlur: propOnBlur,
@@ -224,10 +257,11 @@ const InputToggle = forwardRef<HTMLInputElement, Props>(function InputToggle(
224257
{...props}
225258
{...handlers}
226259
ref={ref}
260+
style={inputStyle}
227261
disabled={disabled}
228262
onFocus={onFocus}
229263
onBlur={onBlur}
230-
className={block("input")}
264+
className={cn(block("input"), inputClassName)}
231265
/>
232266
<span
233267
style={iconStyle}

packages/form/src/toggle/__tests__/InputToggle.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,34 @@ describe("InputToggle", () => {
1515
rerender(<InputToggle {...props} type="checkbox" />);
1616
expect(container).toMatchSnapshot();
1717
});
18+
19+
it("should correctly pass the inputStyle and inputClassName to the invisible input element", () => {
20+
const props = {
21+
id: "toggle",
22+
style: { color: "orange" },
23+
className: "custom-container",
24+
inputStyle: { color: "red" },
25+
inputClassName: "custom-input",
26+
};
27+
28+
const { container, rerender, getByRole } = render(
29+
<InputToggle type="checkbox" {...props} />
30+
);
31+
32+
const toggleContainer = container.firstElementChild as HTMLDivElement;
33+
expect(toggleContainer.style.color).toBe("orange");
34+
expect(toggleContainer.className).toContain(props.className);
35+
const checkbox = getByRole("checkbox");
36+
expect(checkbox.style.color).toBe("red");
37+
expect(checkbox.className).toContain(props.inputClassName);
38+
expect(container).toMatchSnapshot();
39+
40+
rerender(<InputToggle type="radio" value="a" {...props} />);
41+
const radio = getByRole("radio");
42+
expect(toggleContainer.style.color).toBe("orange");
43+
expect(toggleContainer.className).toContain(props.className);
44+
expect(radio.style.color).toBe("red");
45+
expect(radio.className).toContain(props.inputClassName);
46+
expect(container).toMatchSnapshot();
47+
});
1848
});

packages/form/src/toggle/__tests__/__snapshots__/InputToggle.tsx.snap

+53
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,58 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`InputToggle should correctly pass the inputStyle and inputClassName to the invisible input element 1`] = `
4+
<div>
5+
<div
6+
class="rmd-toggle-container custom-container"
7+
style="color: orange;"
8+
>
9+
<span
10+
class="rmd-toggle"
11+
>
12+
<input
13+
class="rmd-toggle__input custom-input"
14+
id="toggle"
15+
style="color: red;"
16+
type="checkbox"
17+
/>
18+
<span
19+
class="rmd-toggle__icon rmd-toggle__icon--overlay"
20+
/>
21+
<span
22+
class="rmd-ripple-container"
23+
/>
24+
</span>
25+
</div>
26+
</div>
27+
`;
28+
29+
exports[`InputToggle should correctly pass the inputStyle and inputClassName to the invisible input element 2`] = `
30+
<div>
31+
<div
32+
class="rmd-toggle-container custom-container"
33+
style="color: orange;"
34+
>
35+
<span
36+
class="rmd-toggle"
37+
>
38+
<input
39+
class="rmd-toggle__input custom-input"
40+
id="toggle"
41+
style="color: red;"
42+
type="radio"
43+
value="a"
44+
/>
45+
<span
46+
class="rmd-toggle__icon rmd-toggle__icon--circle rmd-toggle__icon--overlay"
47+
/>
48+
<span
49+
class="rmd-ripple-container"
50+
/>
51+
</span>
52+
</div>
53+
</div>
54+
`;
55+
356
exports[`InputToggle should render correctly 1`] = `
457
<div>
558
<div

0 commit comments

Comments
 (0)