Skip to content

Commit a41998c

Browse files
committed
1.0.3
* Adding FAQ section to docs * Passing type refinement logic to child and render prop functions * Adding snapshot tests
1 parent ab32bd2 commit a41998c

File tree

11 files changed

+316
-11
lines changed

11 files changed

+316
-11
lines changed

docs/src/index.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import DisableLock from './sections/DisableLock';
1616
import Size from './sections/Size';
1717
import PrettyRadio from './sections/Radio';
1818
import Customize from './sections/Customize';
19+
import FAQ from './sections/FAQ';
1920

2021
import './styles/app.scss';
2122

@@ -69,9 +70,9 @@ function App() {
6970
</a>
7071
</li>
7172
<li className="nav-item">
72-
<a className="nav-link" href="#more">
73-
<i className="mdi mdi-dots-horizontal"></i>
74-
<span className="d-none d-sm-inline">More</span>
73+
<a className="nav-link" href="#faq">
74+
<i className="mdi mdi-help-circle"></i>
75+
<span className="d-none d-sm-inline">FAQ</span>
7576
</a>
7677
</li>
7778
</ul>
@@ -122,6 +123,9 @@ function App() {
122123
<div className="col-md-8 mx-auto">
123124
<section className="section" id="scss-settings"><Customize /></section>
124125
</div>
126+
<div className="col-md-8 mx-auto">
127+
<section className="section" id="faq"><FAQ /></section>
128+
</div>
125129
</div>
126130
<div className="footer text-center">Made with ❤ by Dennis Thompson</div>
127131
</>

docs/src/sections/FAQ.js

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// @flow
2+
3+
import * as React from 'react';
4+
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
5+
import { darcula } from 'react-syntax-highlighter/dist/styles/prism';
6+
7+
// import { Checkbox } from 'pretty-checkbox-react';
8+
9+
import { Title } from '../components/Title';
10+
// import { CollapseContainer } from '../components/CollapseContainer';
11+
12+
const scss = `// @import ...
13+
14+
.#{$pretty--class-name}.my-icon {
15+
@extend .#{$pretty--class-name}.p-icon;
16+
}`;
17+
18+
const jsx = `import { Checkbox } from 'pretty-checkbox-react';
19+
20+
<Checkbox className="my-icon"
21+
icon={<i className="fas fas-question-circle" />}>
22+
Label
23+
</Checkbox>`;
24+
25+
const customRender = `<Checkbox>{({ className, node }) => (
26+
<div className={classNames("state", className, "custom-handle")}>
27+
<label>My custom label</label>
28+
</div>
29+
)}</Checkbox>`;
30+
31+
const QA = ({ title, children }: { title: React.Node, children: React.Node }) => (
32+
<li>
33+
<p className="q-title">{title}</p>
34+
<p className="q-resp">{children}</p>
35+
</li>
36+
);
37+
38+
function FAQ() {
39+
return (
40+
<>
41+
<Title>FAQ</Title>
42+
<div className="content">
43+
<ol>
44+
<QA title={<>Formik overrides <code>p-icon</code> styles</>}>
45+
If you are using Formik and adding a pretty-checkbox or pretty-checkbox-react component, then you might be seeing visual discrepancies.
46+
We can get around this by using the render prop or child render function exposed by <strong>pretty-react-checkbox</strong>.
47+
The easiest way to get around this is to custom build pretty-checkbox <code>.scss</code> source files.
48+
Once you have that in place we need to make a few tweaks.
49+
<SyntaxHighlighter language="scss" style={darcula}>{scss}</SyntaxHighlighter>
50+
With the magic of using Sass <code>@extends</code> we can essentially "copy" the pretty-checkbox base styles to our own selector.
51+
After this, our usage becomes a bit different as well.
52+
<SyntaxHighlighter language="jsx" style={darcula}>{jsx}</SyntaxHighlighter>
53+
Formik will still apply styles to <code>p-icon</code>, but the styles shouldn't clash anymore.
54+
</QA>
55+
<QA title="How can I customize pretty-checkbox state div?">
56+
Good question! All components offer <code>render</code> prop and <code>children</code> render function support. It's as easy as this:
57+
<SyntaxHighlighter language="jsx" style={darcula}>{customRender}</SyntaxHighlighter>
58+
By default the function will return an object containing a <code>className</code> that can be applied -- this is inferred based on the props you pass your base component.
59+
You can ignore these outright if you wish. Using this approach you can also harness the states exposed by pretty-checkbox.
60+
</QA>
61+
</ol>
62+
</div>
63+
</>
64+
);
65+
}
66+
67+
export default FAQ;

src/components/Input.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ type Icon = {|
3030
icon: React.Element<any>
3131
|};
3232

33+
type Node = {|
34+
className: string,
35+
node: any
36+
|} | null;
37+
3338
type BaseProps = {
3439
/**
3540
* Select the type if component: checkbox or radio.
@@ -43,7 +48,7 @@ type BaseProps = {
4348
* **Note:** You are responsible for providing
4449
* the details of pretty-checkbox's `div.state`.
4550
*/
46-
children?: React.Node | (() => React.Node),
51+
children?: React.Node | ((Node) => React.Node),
4752

4853
/**
4954
* Customize the rendering of the checkbox, radio,
@@ -52,7 +57,7 @@ type BaseProps = {
5257
* **Note:** You are responsible for providing
5358
* the details of pretty-checkbox's `div.state`.
5459
*/
55-
render?: (() => React.Node),
60+
render?: ((Node) => React.Node),
5661

5762
/**
5863
* The style of the checkbox or radio.
@@ -165,10 +170,7 @@ const fillClassNameForIcons = (component: React.Element<any> | void, className:
165170
* Handles custom or default rendering of the pretty-checkbox `div.state` class.
166171
*/
167172
const PrettyInputState = (props: InputProps): React.Node => {
168-
let node: {|
169-
className: string,
170-
node: any
171-
|} | null = null;
173+
let node: Node = null;
172174

173175
const { children, render, id, color } = props;
174176

@@ -191,11 +193,11 @@ const PrettyInputState = (props: InputProps): React.Node => {
191193
}
192194

193195
if (typeof children === 'function') {
194-
return children();
196+
return children(node);
195197
}
196198

197199
if (typeof render === 'function') {
198-
return render();
200+
return render(node);
199201
}
200202

201203
return (

src/components/__tests__/Checkbox.test.js

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe('Checkbox tests', function () {
2525

2626
expect(handleChange).toHaveBeenCalledTimes(2);
2727
expect(getByTestId(container, 'pcr-input').checked).toBe(false);
28+
expect(container).toMatchSnapshot();
2829
});
2930

3031
it('should render icons with the correct classNames', function () {

src/components/__tests__/Input.test.js

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ describe('Input tests', function () {
1515

1616
rerender(<Input type="checkbox" render={() => <p data-testid="custom-test">Hello</p>} />);
1717
expect(() => getByTestId(container, 'custom-test')).not.toThrow();
18+
expect(container).toMatchSnapshot();
1819
});
1920
});
2021

src/components/__tests__/Radio.test.js

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe('Radio tests', function () {
2525

2626
expect(handleChange).toHaveBeenCalledTimes(1);
2727
expect(getByTestId(container, 'pcr-input').checked).toBe(true);
28+
expect(container).toMatchSnapshot();
2829
});
2930

3031
it('should behave as a radio group', function () {
@@ -60,6 +61,7 @@ describe('Radio tests', function () {
6061
expect(r1.checked).toBe(false);
6162
expect(r2.checked).toBe(false);
6263
expect(r3.checked).toBe(true);
64+
expect(container).toMatchSnapshot();
6365
});
6466

6567
it('should render icons with the correct classNames', function () {

src/components/__tests__/Switch.test.js

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ describe('Switch tests', function () {
4242

4343
expect(handleChange).toHaveBeenCalledTimes(1);
4444
expect(getByTestId(container, 'pcr-input').checked).toBe(true);
45+
expect(container).toMatchSnapshot();
4546
});
4647

4748
it('should behave as a radio group', function () {
@@ -77,6 +78,7 @@ describe('Switch tests', function () {
7778
expect(r1.checked).toBe(false);
7879
expect(r2.checked).toBe(false);
7980
expect(r3.checked).toBe(true);
81+
expect(container).toMatchSnapshot();
8082
});
8183
});
8284

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Checkbox tests Basic Checkbox usage should behave as a checkbox 1`] = `
4+
<div>
5+
<div
6+
class="pretty p-default"
7+
data-testid="pcr-wrapper"
8+
>
9+
<input
10+
data-testid="pcr-input"
11+
id="foo"
12+
type="checkbox"
13+
value=""
14+
/>
15+
<div
16+
class="state"
17+
data-testid="pcr-state"
18+
/>
19+
</div>
20+
</div>
21+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Input tests Input custom rendering should support custom rendering via render prop and children render function 1`] = `
4+
<div>
5+
<div
6+
class="pretty"
7+
data-testid="pcr-wrapper"
8+
>
9+
<input
10+
data-testid="pcr-input"
11+
type="checkbox"
12+
value=""
13+
/>
14+
<p
15+
data-testid="custom-test"
16+
>
17+
Hello
18+
</p>
19+
</div>
20+
</div>
21+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Radio tests Radio usage as a radio should behave as a radio 1`] = `
4+
<div>
5+
<div
6+
class="pretty p-default p-round"
7+
data-testid="pcr-wrapper"
8+
>
9+
<input
10+
data-testid="pcr-input"
11+
id="foo"
12+
type="radio"
13+
value=""
14+
/>
15+
<div
16+
class="state"
17+
data-testid="pcr-state"
18+
/>
19+
</div>
20+
</div>
21+
`;
22+
23+
exports[`Radio tests Radio usage as a radio should behave as a radio group 1`] = `
24+
<div>
25+
<div
26+
class="pretty p-default p-round"
27+
data-testid="pcr-wrapper"
28+
>
29+
<input
30+
data-testid="pcr-input"
31+
id="demo"
32+
name="radio-1"
33+
type="radio"
34+
value="r1"
35+
/>
36+
<div
37+
class="state"
38+
data-testid="pcr-state"
39+
>
40+
<label
41+
for="demo"
42+
>
43+
Hello there.
44+
</label>
45+
</div>
46+
</div>
47+
<div
48+
class="pretty p-default p-round"
49+
data-testid="pcr-wrapper"
50+
>
51+
<input
52+
data-testid="pcr-input"
53+
id="demo"
54+
name="radio-1"
55+
type="radio"
56+
value="r2"
57+
/>
58+
<div
59+
class="state"
60+
data-testid="pcr-state"
61+
>
62+
<label
63+
for="demo"
64+
>
65+
General Kenobi. You are a bold one.
66+
</label>
67+
</div>
68+
</div>
69+
<div
70+
class="pretty p-default p-round"
71+
data-testid="pcr-wrapper"
72+
>
73+
<input
74+
data-testid="pcr-input"
75+
id="demo"
76+
name="radio-1"
77+
type="radio"
78+
value="r3"
79+
/>
80+
<div
81+
class="state"
82+
data-testid="pcr-state"
83+
>
84+
<label
85+
for="demo"
86+
>
87+
Your move.
88+
</label>
89+
</div>
90+
</div>
91+
</div>
92+
`;

0 commit comments

Comments
 (0)