Testing SVGR as React Component with Jest - reactjs

Getting a warning when running test on svg component. It's not causing the test to fail but trying to get it cleaned up. Using SVGR to use svg files as react components. I believe the issue is Jest isn't able to see the svgr configuration in webpack, but not sure how to fix it.
Warning
console.error
Warning: <ReactComponent /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
at ReactComponent
at Icon (/code/common/javascript/components-2.0/lib/brand/Icon/index.tsx:9:11)
import { SvgIndexable } from "./Icon.types";
import { ReactComponent as ArrowRight } from "./svg/arrow-right.svg";
const iconNames: SvgIndexable = {
"arrow-right": ArrowRight,
}
export default iconNames
index.js
import React from "react";
import className from "classnames";
import { IconTypes } from "./Icon.types";
import iconNames from "./Icon.Components";
import styles from "./Icon.module.scss";
const Icon: React.FC<IconTypes> = (props: IconTypes): JSX.Element| null => {
const { id, name, extraClass, color = "black", size = "medium" } = props;
const iconClasses = className(styles[size], styles[color], extraClass);
const IconComponent = iconNames[name];
if (typeof iconNames[name] !== "undefined") {
return React.createElement(
iconNames[name],
{
id:id,
className:iconClasses,
"data-testid":`test__${id}-icon`,
},
null
);
} else {
return null;
}
};
export default Icon;
jest.config.json
"moduleNameMapper": {
"^#/(.*)$": "<rootDir>/lib/$1",
"components-2.0": "<rootDir>/__mocks__/components-2.0
"\\.(pdf|jpg|jpeg|png|gif|ico|xml|manifestjson|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "identity-obj-proxy",
"\\.svg$": "<rootDir>/__mocks__/components-2.0/svgrMock.js"
},
svgrMock.js
import * as React from "react";
export default "SvgrURL";
export const ReactComponent = "div";

Related

Published styled-components UI library does not have access to extended theme types on the consumer side

I am creating UI library using styled-components. I am extending the DefaultTheme type to support custom themes that are needed for our use case. Both theme and theme definition is coming from a different internal package that I use. When working on the UI library components, it works correctly. The issue begins when we tried to use the theming on the consumer side.
The problem is that, it seems that types are not really extended to the consumer correctly, so without adding styled.d.ts file on the client side, it doesn't seem to understand the types of the theme. Theme get a type anyand it should be read asDefaultTheme type.
I wonder if there is any way to expose the extended types to consumer so they don't have to add this additional file on their side?
Is there anyone out there who had similar problem? Maybe you could share your findings?
Here is my setup:
Design System project:
// theme.ts
import tokens from 'my-external-package/variables.json';
import type { ThemeProps } from 'styled-components';
import type { MyThemeType } from 'my-external-package//theme';
const { light, dark } = tokens.color.theme;
export const lightTheme = {
color: light,
};
export const darkTheme = {
color: dark,
};
export const defaultTheme = lightTheme;
// styled.d.ts
import {} from 'styled-components';
import type { MyThemeType } from 'my-external-package//theme';
// extend theme
declare module 'styled-components' {
// eslint-disable-next-line #typescript-eslint/no-empty-interface
export interface DefaultTheme extends MyThemeType {}
}
// CustomThemeProvider.tsx
import React, { createContext, useState, ReactNode, useContext } from 'react';
import { ThemeProvider } from 'styled-components';
import { lightTheme, darkTheme } from './theme';
const themes = {
light: lightTheme,
dark: darkTheme,
};
type CustomThemeProviderProps = {
children: ReactNode;
defaultTheme?: keyof typeof themes;
};
const themeContext = createContext({ toggleTheme: () => {} });
const { Provider } = themeContext;
export const CustomThemeProvider = ({
children,
defaultTheme = 'light',
}: CustomThemeProviderProps) => {
const [currentTheme, setCurrentTheme] = useState(defaultTheme);
return (
<Provider
value={{
toggleTheme: () =>
setCurrentTheme((current) => current === 'light' ? 'dark' : 'light'),
}}
>
<ThemeProvider theme={themes[currentTheme]}>{children}</ThemeProvider>
</Provider>
);
};
// I also export hook over here so I can use it on the client side
export const useToggleTheme = () => {
const { toggleTheme } = useContext(themeContext);
return toggleTheme;
};
App consumer NextJs
//_app.tsx
import type { AppProps } from 'next/app';
import { CustomThemeProvider } from 'my-library-package/theming';
function MyApp({ Component, pageProps }: AppProps) {
return (
<CustomThemeProvider defaultTheme='light'>
<Component {...pageProps} />
</CustomThemeProvider>
);
}
export default MyApp;
// consumer_page.tsx
import type { NextPage } from 'next';
import { useCallback, useState } from 'react';
import styled from 'styled-components';
import tokens from 'my-external-package/variables.json';
import { useToggleTheme, Switch } from 'my-library-package';
const CustomComponent = styled.p`
color: ${({ theme }) => theme.color.feedback.success.foreground};
`;
const MyPage: NextPage = () => {
const toggleTheme = useToggleTheme();
return (
<>
<Switch onChange={toggleTheme}/>
<CustomComponent>This component have access to theme</CustomComponent>
</>
)
}
export default MyPage;
We are considering re-export utilities from styled-components with the right DefaultTheme and instruct consumers not to install styled-components
Instruct design-system consumers to create a styled.d.ts file to get the theme correctly populated.
Both of those seems rather painful. :(

extending default theme chakra ui

I want to set default borderColor to all Input components but it doesn't work
This is my theme.js file:
import { extendTheme } from "#chakra-ui/react";
const config = {
initialColorMode: "light",
useSystemColorMode: false,
};
const theme = extendTheme({
config,
components: {
Input: {
borderColor: "teal",
},
},
});
export default theme;
Input is a multi-part component. You can figure out if the component you're trying to customise is single-part or multi-part by going to the docs for that component and clicking the View theme source button at the top of the page:
How to customise the theme: Docs
How to customise single-part and multi-part components: Docs (especially, how to customise multi-part components)
So in your case you need do something like this:
index.js :
import * as React from "react";
import { render } from "react-dom";
import { ChakraProvider, extendTheme } from "#chakra-ui/react";
import App from "./App";
const Input = {
variants: {
filled: () => ({
field: {
borderColor: "teal"
}
})
}
};
const theme = extendTheme({
components: {
Input
}
});
const rootElement = document.getElementById("root");
render(
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>,
rootElement
);
App.js :
import * as React from "react";
import { Input } from "#chakra-ui/react";
export default function App() {
return <Input placeholder="extra small size" variant="filled" />;
}

how to load scss module as object?

According to Using SASS#3
By default, Laravel Mix will handle any import for SASS files. This means that anytime you do a import styles from 'blabla.scss', Mix will fetch that object and parse its CSS.
in my case CSS Modules can not operate properly with Laravel Mix (4.1.4)/ React 16.2.0
// webpack.mix.js
const mix = require('laravel-mix');
let rules = [
{
test: /\.ico$/,
loaders: ['file-loader']
}
];
mix.react('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.webpackConfig(
{
module: {
rules: rules
}
}
);
mix.browserSync('localhost:8000');
I'm trying to import a SCSS module like this:
my React component Progress.js
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {
Progress as BsProgress
} from 'reactstrap';
import classes from './../../../sass/Progress.scss';
const Progress = (props) => {
const { children, slim, className, ...otherProps } = props;
const progressClass = classNames(className, {
[classes['slim']]: slim
});
return (
<BsProgress className={ progressClass } { ...otherProps }>
{ !slim && children }
</BsProgress>
);
};
Progress.propTypes = {
slim: PropTypes.bool,
className: PropTypes.string,
children: PropTypes.node
};
export { Progress };
Just try importing a .module.scss
import classes from './../../../sass/Progress.module.scss'

How to write unit test case for formik using react?

I'm trying to write unit test case for react application. I using formik to handle form submission. In formik form we are using FieldArray component of formik. how to write test case for this?
import React from "react"
import { shallow } from "enzyme"
import { AdditionalCustomFields } from "./index"
import { additionalData, customFieldData} from "../../../../mockData"
import { settingStyles } from "../../../../../common/Styles"
import { withStyles } from "#material-ui/core/styles"
import PropTypes from "prop-types"
const props = {
values : {
additionalData,
customFieldData
}
}
const Composer = ({ classes}) =>{
return <AdditionalCustomFields classes={classes} {...props}/>
}
Composer.propTypes = {
classes: PropTypes.object.isRequired
}
const Composition = withStyles(settingStyles)(Composer)
describe("Composer",()=>{
const wrapper = shallow(<Composition />).dive().find(AdditionalCustomFields).shallow()
it("Describe CustomFieldForm component",()=>{
console.log("sub component========>", wrapper.debug())
})
})
I'm getting this instead of my component structure:-
PASS src/pages/Settings/components/Application/components/CustomFields/components/CustomFieldForm/component/AdditionalCustomFields/AdditionalCustomFields.test.js
● Console
console.log src/pages/Settings/components/Application/components/CustomFields/components/CustomFieldForm/component/AdditionalCustomFields/AdditionalCustomFields.test.js:31
sub component========> <WithStyles(ForwardRef(Grid)) container={true}>
<FormikConnect(FieldArrayInner) name="additionalData" render={[Function: render]} />
</WithStyles(ForwardRef(Grid))>

How to pass React context in tests for Higher Order Components using enzyme

I'm trying to test a Button Component that's render with styles (withStyles())
The problem is that withStyles needs to have access to a theme.
This is an attempt at writing the mounting functions.
import React from 'react';
import { mount, shallow } from 'enzyme';
import {
withStyles,
createGenerateClassName,
createMuiTheme,
jssPreset,
MuiThemeProvider,
getMuiTheme
} from 'material-ui/styles';
import PropTypes from 'prop-types';
import globalThem from 'client/theme/base';
const theme = createMuiTheme(globalThem);
const { muiThemeProviderOptions } = (new MuiThemeProvider({ theme }, {})).getChildContext()
export const shallowWithStyles = node => shallow(
node,
{
context: { muiThemeProviderOptions },
}
)
export const mountWithStyles = node => mount(
node,
{
context: { muiThemeProviderOptions },
}
)

Resources