Skip to content

Commit ae21889

Browse files
committed
chore: integrate plop and bug fix
1 parent a5080d0 commit ae21889

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1416
-454
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export { default as {{ name }} } from './{{ name }}';
2+
export type { {{ getInterface name }} } from './types';
3+
// above is boilerplate stuff
4+
// replace with your component & props
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
export const colorState = ['greenLight', 'redLight'] as const;
2+
export type TColorState = typeof colorState[number];
3+
import { color } from '@web3uikit/styles';
4+
5+
export type Colors = keyof typeof color;
6+
7+
// NOTE: the comment strings are very important
8+
// Storybook pulls them to make our docs
9+
10+
export interface {{ getInterface name }} {
11+
/**
12+
* Set the Background color of New Component
13+
*/
14+
bgColor?: Colors;
15+
/**
16+
* The New Component needs text for its green light state
17+
*/
18+
textOn: string;
19+
20+
/**
21+
* The New Component needs text for its red light state
22+
*/
23+
textOff: string;
24+
25+
/**
26+
* Set the initial state from the New Component
27+
*/
28+
state?: TColorState;
29+
30+
/**
31+
* Set the text to have an underline
32+
*/
33+
hasUnderline?: boolean;
34+
35+
/**
36+
* The callback function to be called on click
37+
*/
38+
onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// importing boilerplate stuff for Storybook
2+
import React from 'react';
3+
import { ComponentStory, ComponentMeta } from '@storybook/react';
4+
// importing your new component
5+
import {{ name }} from './{{ name }}';
6+
7+
// title: group / name in Storybook
8+
// component: your new component
9+
// argTypes: onClick is a 'Storybook Event' to simulate clicks
10+
export default {
11+
title: '{{ category }}/{{ name }}',
12+
component: {{ name }},
13+
argTypes: { onClick: { action: 'clicked' } },
14+
} as ComponentMeta<typeof {{ name }}>;
15+
16+
// another boilerplate to set up your Storybook template with your new component
17+
const Template: ComponentStory<typeof {{ name }}> = (args) => (
18+
<{{ name }} {...args} />
19+
);
20+
21+
//////////////////////////////////////////////////////////////////////////////
22+
// NOTE please only include the min props needed for each render
23+
// this means the next dev using 'get code' in Storybook will not get confused
24+
//////////////////////////////////////////////////////////////////////////////
25+
26+
// Story 1 Default
27+
export const Default = Template.bind({});
28+
Default.args = {
29+
textOn: 'green light',
30+
textOff: 'red light!',
31+
};
32+
33+
// Story 2 InitializeRed
34+
export const InitializeRed = Template.bind({});
35+
InitializeRed.args = {
36+
textOn: 'green light',
37+
textOff: 'red light!',
38+
state: 'redLight',
39+
};
40+
41+
// Story 3 UnderLinedText
42+
export const UnderLinedText = Template.bind({});
43+
UnderLinedText.args = {
44+
textOn: 'green light',
45+
textOff: 'red light!',
46+
hasUnderline: true,
47+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// importing styled to make components and css to make themes
2+
import styled, { css } from 'styled-components';
3+
4+
// importing centralized styles
5+
import {color, fonts, resetCSS} from '@web3uikit/styles';
6+
7+
// import our types to conditionally render CSS
8+
import type { {{ getInterface name }} } from './types';
9+
10+
// pick the props that you will use for conditional CSS
11+
type TStyleProps = Pick<{{ getInterface name }}, 'state' | 'hasUnderline' | 'bgColor'>;
12+
13+
// //////////////////
14+
// Theme CSS
15+
// CSS Props should be sorted alphabetically
16+
// //////////////////
17+
const greenColor = css`
18+
color: ${color.green};
19+
`;
20+
const redColor = css`
21+
color: ${color.red};
22+
`;
23+
24+
// //////////////////
25+
// Styled Components
26+
// CSS Props should be sorted alphabetically
27+
// //////////////////
28+
const SectionStyled = styled.section<TStyleProps>`
29+
border-bottom: 5px solid ${color.green};
30+
border-top: 5px solid ${color.yellow};
31+
padding: 12px 24px;
32+
background-color: ${(p) => p.bgColor && color[p.bgColor]};
33+
`;
34+
35+
const SpanStyled = styled.span`
36+
display: flex;
37+
align-items: center;
38+
39+
svg {
40+
margin-right: 8px;
41+
}
42+
`;
43+
44+
const TitleStyled = styled.h1<TStyleProps>`
45+
${resetCSS};
46+
${fonts.heading};
47+
${fonts.h1};
48+
margin-bottom: 12px;
49+
`;
50+
51+
const HeadingStyled = styled.h2<TStyleProps>`
52+
${resetCSS};
53+
${fonts.heading};
54+
${fonts.h2};
55+
margin-bottom: 12px;
56+
${(p) => (p.state === 'greenLight' ? greenColor : redColor)};
57+
`;
58+
59+
const TextStyled = styled.p<TStyleProps>`
60+
${resetCSS};
61+
${fonts.heading};
62+
${fonts.text};
63+
margin-top: 12px;
64+
text-decoration: ${(p) => (p.hasUnderline ? 'underline' : 'none')}; ;
65+
`;
66+
67+
// CSS ORDERING
68+
// 1 - Imported styles (font, colors, etc)
69+
// 2 - Normal styles (margin, padding, etc)
70+
// 3 - Child elements (span, svg, etc)
71+
// 4 - Pseudo elements (before & after)
72+
// 5 - Modifier styles (hover, active etc)
73+
// 6 - State changed styles ${(p) => (p.prop ? green : red)};
74+
// each should be sorted alphabetically as best as possible
75+
76+
export default {
77+
HeadingStyled,
78+
SectionStyled,
79+
SpanStyled,
80+
TextStyled,
81+
TitleStyled,
82+
greenColor,
83+
redColor,
84+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
// importing boilerplate stuff
2+
import React from 'react';
3+
import { composeStories } from '@storybook/testing-react';
4+
import { render, screen, fireEvent } from '@testing-library/react';
5+
import * as stories from './{{ name }}.stories';
6+
7+
// // importing fire event from RTL to mock a click event
8+
// import { fireEvent } from '@testing-library/react';
9+
10+
// importing color and a testing tool to convert RGB to HEX
11+
import {color,rgbToHex} from '@web3uikit/styles';
12+
13+
// importing testID from button and icon
14+
import { buttonTestId } from '../Button/Button.test';
15+
16+
const iconTestId = 'test-icon';
17+
18+
// importing my stories to test
19+
const { Default, InitializeRed, UnderLinedText } = composeStories(stories);
20+
21+
// setting my test IDs to match my tsx
22+
export const testCompId = 'test-new-comp';
23+
const testTitle = 'test-title';
24+
const testHeading = 'test-heading';
25+
const testText = 'test-text';
26+
// NOTE: the main test ID is exported incase
27+
// it is needed for another components test
28+
29+
// /////////////////////////////////////////////////////
30+
// examples of basic tests of props, values and styles
31+
// /////////////////////////////////////////////////////
32+
33+
// Test Story 1: Default
34+
test('Renders Default component', () => {
35+
const testTextOn = Default?.args?.textOn;
36+
37+
render(<Default />);
38+
39+
const component = screen.getByTestId(testCompId);
40+
expect(component).not.toBeNull();
41+
42+
const icon = screen.getByTestId(iconTestId);
43+
expect(icon).not.toBeNull();
44+
45+
const title = screen.getByTestId(testTitle);
46+
expect(title).not.toBeNull();
47+
expect(title.textContent).toBe('The Demo Component');
48+
49+
const heading = screen.getByTestId(testHeading);
50+
expect(heading).not.toBeNull();
51+
expect(heading.textContent).toBe(testTextOn);
52+
53+
const styles = heading && getComputedStyle(heading);
54+
const colorHex = styles && rgbToHex(styles.color).toUpperCase();
55+
expect(colorHex).toBe(color.green);
56+
57+
const text = screen.getByTestId(testText);
58+
expect(text).not.toBeNull();
59+
expect(text.textContent).toBe('Clicked: 0 times');
60+
61+
const textWithoutUnderline = screen.getByTestId(testText);
62+
expect(textWithoutUnderline).not.toBeNull();
63+
const twlStyles =
64+
textWithoutUnderline && getComputedStyle(textWithoutUnderline);
65+
expect(twlStyles?.textDecoration).toBe('none');
66+
});
67+
68+
// Test Story 2: Button Click
69+
test('changes UI onClick of the button', () => {
70+
const testTextOff = Default?.args?.textOff;
71+
72+
render(<Default />);
73+
74+
const buttonElement = screen.getByTestId(buttonTestId);
75+
76+
buttonElement && fireEvent.click(buttonElement);
77+
78+
const textElelement = screen.getByTestId(testText);
79+
expect(textElelement).not.toBeNull();
80+
expect(textElelement.textContent).toBe('Clicked: 1 times');
81+
82+
const headingElement = screen.getByTestId(testHeading);
83+
expect(headingElement).not.toBeNull();
84+
expect(headingElement.textContent).toBe(testTextOff);
85+
86+
const styles = headingElement && getComputedStyle(headingElement);
87+
const colorHex = styles && rgbToHex(styles.color).toUpperCase();
88+
expect(colorHex).toBe(color.red);
89+
});
90+
91+
// Test Story 3: InitializeRed
92+
test('Renders InitializeRed', () => {
93+
const testTextOff = InitializeRed?.args?.textOff;
94+
95+
render(<InitializeRed />);
96+
97+
const component = screen.getByTestId(testCompId);
98+
expect(component).not.toBeNull();
99+
100+
const icon = screen.getByTestId(iconTestId);
101+
expect(icon).not.toBeNull();
102+
103+
const title = screen.getByTestId(testTitle);
104+
expect(title).not.toBeNull();
105+
expect(title.textContent).toBe('The Demo Component');
106+
107+
const heading = screen.getByTestId(testHeading);
108+
expect(heading).not.toBeNull();
109+
expect(heading.textContent).toBe(testTextOff);
110+
111+
const styles = heading && getComputedStyle(heading);
112+
const colorHex = styles && rgbToHex(styles.color).toUpperCase();
113+
expect(colorHex).toBe(color.red);
114+
115+
const text = screen.getByTestId(testText);
116+
expect(text).not.toBeNull();
117+
expect(text.textContent).toBe('Clicked: 0 times');
118+
119+
const textWithoutUnderline = screen.getByTestId(testText);
120+
expect(textWithoutUnderline).not.toBeNull();
121+
const twlStyles =
122+
textWithoutUnderline && getComputedStyle(textWithoutUnderline);
123+
expect(twlStyles?.textDecoration).toBe('none');
124+
});
125+
126+
// Test Story 3: Button click
127+
test('changes UI onClick of the button', () => {
128+
const testTextOn = InitializeRed?.args?.textOn;
129+
130+
render(<InitializeRed />);
131+
132+
const buttonElement = screen.getByTestId(buttonTestId);
133+
buttonElement && fireEvent.click(buttonElement);
134+
135+
const textElelement = screen.getByTestId(testText);
136+
expect(textElelement).not.toBeNull();
137+
expect(textElelement.textContent).toBe('Clicked: 1 times');
138+
139+
const headingElement = screen.getByTestId(testHeading);
140+
expect(headingElement).not.toBeNull();
141+
expect(headingElement.textContent).toBe(testTextOn);
142+
143+
const styles = headingElement && getComputedStyle(headingElement);
144+
const colorHex = styles && rgbToHex(styles.color).toUpperCase();
145+
expect(colorHex).toBe(color.green);
146+
});
147+
148+
// Test Story 4: UnderLinedText
149+
test('Renders UnderLinedText', () => {
150+
const testTextOn = UnderLinedText?.args?.textOn;
151+
152+
render(<UnderLinedText />);
153+
154+
const component = screen.getByTestId(testCompId);
155+
expect(component).not.toBeNull();
156+
157+
const icon = screen.getByTestId(iconTestId);
158+
expect(icon).not.toBeNull();
159+
160+
const title = screen.getByTestId(testTitle);
161+
expect(title).not.toBeNull();
162+
expect(title.textContent).toBe('The Demo Component');
163+
164+
const heading = screen.getByTestId(testHeading);
165+
expect(heading).not.toBeNull();
166+
expect(heading.textContent).toBe(testTextOn);
167+
168+
const styles = heading && getComputedStyle(heading);
169+
const colorHex = styles && rgbToHex(styles.color).toUpperCase();
170+
expect(colorHex).toBe(color.green);
171+
172+
const text = screen.getByTestId(testText);
173+
expect(text).not.toBeNull();
174+
expect(text.textContent).toBe('Clicked: 0 times');
175+
176+
const textWithoutUnderline = screen.queryByTestId(testText);
177+
expect(textWithoutUnderline).not.toBeNull();
178+
const twlStyles =
179+
textWithoutUnderline && getComputedStyle(textWithoutUnderline);
180+
expect(twlStyles?.textDecoration).toBe('underline');
181+
});
182+
183+
test('changes UI onClick of the button', () => {
184+
const testTextOff = UnderLinedText?.args?.textOff;
185+
186+
render(<UnderLinedText />);
187+
188+
const buttonElement = screen.getByTestId(buttonTestId);
189+
buttonElement && fireEvent.click(buttonElement);
190+
191+
const textElelement = screen.getByTestId(testText);
192+
expect(textElelement).not.toBeNull();
193+
expect(textElelement.textContent).toBe('Clicked: 1 times');
194+
195+
const headingElement = screen.getByTestId(testHeading);
196+
expect(headingElement).not.toBeNull();
197+
expect(headingElement.textContent).toBe(testTextOff);
198+
199+
const styles = headingElement && getComputedStyle(headingElement);
200+
const colorHex = styles && rgbToHex(styles.color).toUpperCase();
201+
expect(colorHex).toBe(color.red);
202+
});

0 commit comments

Comments
 (0)