I'm trying to configure storybook to display a dark theme, and so far i didn't find any solution to this problem.
so i followed the storybook docs,
and i'v setup the manager.js file like so:
// .storybook/manager.js
import { addons } from '#storybook/addons';
import { themes } from '#storybook/theming';
addons.setConfig({
theme: themes.dark,
});
i'v also printed the theme to the console so i see it arrives:
it may be worth mentioning that when the browser reload this file is read,
but if i change the source code and save the hot-reload don't work..
Here's how i specified the same theme for docs in .storybook/preview.js:
// .storybook/preview.js
import React from "react";
import { appTheme } from "../src/Common/theme";
import { ThemeProvider } from "styled-components";
import { makeDecorator } from "#storybook/addons";
import { addParameters, addDecorator } from "#storybook/react";
import defaultNotes from "./general-docs.md";
import { themes } from "#storybook/theming";
export const parameters = {
docs: {
theme: themes.dark
}
};
addParameters({
notes: defaultNotes,
options: {
showRoots: true
}
});
const withStyledTheme = storyFn => {
return <ThemeProvider theme={appTheme}>{storyFn()}</ThemeProvider>;
};
const styledThemed = makeDecorator({
name: "styled-theme",
wrapper: withStyledTheme
});
addDecorator(styledThemed);
addParameters(parameters);
this is how the main.js file looks like:
module.exports = {
stories: ["../src/**/*.stories.(ts|tsx|js|jsx|mdx)"],
addons: [
"#storybook/preset-create-react-app",
"#storybook/addon-actions",
"#storybook/addon-links",
"#storybook/addon-actions/register",
"#storybook/addon-knobs/register",
"#storybook/addon-notes/register-panel",
"storybook-addon-designs",
"#storybook/addon-docs/preset"
]
};
i work with typescript in this project,
so here is the tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"baseUrl": "src"
},
"include": ["src"]
}
What am i missing here ?
I've been stuck on the same problem for a while, but the solution was in the doc all along:
//.storybook/preview.js
import { themes } from '#storybook/theming';
export const parameters = {
docs: {
theme: themes.dark,
},
};
So yeah, you have to specify the theme twice, in two different files
Related
Getting below error
cannot find module #assets/logo-filled.png from src/component/index.tsx
if I replace import logo from #assets/logo-filled.png with import logo from ../../../assets/logo-filled.png
This line of import is working fine while running the application. But while running the test scripts npm test -> react-scripts test the above error is popping up
test.test.tsx
import React from "react";
import { render } from "#testing-library/react";
import {Logo} from "../components/logo";
describe('Describe...', () => {
test('test ...', () => {
console.log('the test');
render(<Logo withoutText={true}/>);
expect(1).toBe(1)
});
});
Logo.tsx
import React from 'react';
import { Stack, Image, Text } from '#fluentui/react';
import { logoContainerStyles, textStyles } from './styles';
// ERROR thrown by below line
import logo from '#assets/icon-16.png';
// Works fine with below commented line
/** import logo from '../../../assets/icon-16.png'; */
export interface LogoProps {
withoutText?: boolean;
}
export const Logo: React.FC<LogoProps> = props => {
const { withoutText } = props;
return (
<Stack styles={logoContainerStyles} horizontalAlign="center">
<Image src={logo} alt="logo" width={64} shouldFadeIn={false} />
<Text styles={textStyles} variant="xLarge">
Hello StackOverflow
</Text>
</Stack>
);
};
ts.config.json
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"moduleResolution": "node",
"allowJs": true,
"jsx": "react",
"lib": ["esnext", "dom", "dom.iterable"],
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"outDir": "dist",
"noImplicitReturns": true,
"pretty": true,
"typeRoots": ["node_modules/#types"],
"baseUrl": "src",
"paths": {
"#assets/*": ["../assets/*"]
}
},
"include": ["src"]
}
Any kind of help will much be appreciated.
We need a little bit more details on your setup. But it has to do with tsconfig.json and it's paths property. Also take a closer look at jest property in package.json, it is used to define aliases for tests.
In the jest.config.js use ,
moduleNameMapper: {
// Handle other modules
// Handle module aliases
"^#/assets/(.*)$": "<rootDir>/assets/$1",
},
If you want use module aliases with TypeScript
"paths": {
"#/assets/*": ["assets/*"],
}
I'm integrating vitest with a NextJS13 app, but running into problems with a simple test run.
Not sure what the problem is, I tried to do some tweaking with the vitest.config.ts but no luck. I tried adding the dir option, modified the include option to grab files from the source file but no luck.
I thought maybe it had to do with the tsconfig.json file, but it's still outputting the error.
This is the directory of the file
Here are the files in question:
vitest.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vitest/config'
import react from '#vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
setupFiles: 'setupTests.ts',
// dir: './src'
// includeSource: ['src/**/*.{js,ts,tsx}'],
},
});
tsconfig.json
{
"compilerOptions": {
"target": "ES2017",
"lib": ["es6", "dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "ESNEXT",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": ".",
"incremental": true,
// "paths": {
// "src": ["./src/*"]
// }
},
"exclude": ["node_modules"],
"include": ["vitest.config.ts","**/*.ts", "**/*.tsx", "next-env.d.ts",
"next.config.js"]
}
DataTable.test.tsx - src/common/components/DataTable/DataTable.test.tsx
// components
import DataTable from 'src/common/components/DataTable';
// dependencies
import {describe, it} from 'vitest'
import {screen, render} from '#testing-library/react'
describe('DataTable test', () => {
it('render the app', () => {
// arrange
render(<DataTable />)
// act
const assetText = screen.getByText("asset")
// assert
// expect(assetText).toBeInTheDocument()
})
})
DataTable component - src/common/components/DataTable/DataTable.tsx
export const DataTable = () => {
return (
<div>
<h1>assets</h1>
</div>
);
};
Index.tsx - src/common/components/DataTable/index.tsx
import { DataTable } from 'src/common/components/DataTable/DataTable';
export default DataTable;
I'm new to vitest and nextjs, your help/guidance will be appreciated.
There are two things needed here to make the import DataTable from 'src/common/components/DataTable'; import work:
TypeScript needs the paths compilerOption set.
Vite needs to have the same alias set.
The "paths" compilerOption in TypeScript will need a /* on the end of the "src" key to be able to resolve paths underneath the "src" directory (see tsconfig.json reference):
{
"compilerOptions": {
"paths": {
"src/*": ["./src/*"]
}
}
}
Vite/Vitest will also need to know how to resolve "src/common/components/DataTable", and that would usually be done with the resolve.alias setting, but rather than duplicating the alias here, you could also use a plugin, like vite-tsconfig-paths, to add the path aliases if finds in relevant tsconfig.json files:
import react from "#vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
export default {
plugins: [tsconfigPaths(), react()],
};
I need some really basic dependency injection for a react project in a similar syntactical manner as in C# or Java. Using context or injection through props is not an option. I tried three solutions so far:
Inversify
Inversify-React-Decorators
React.DI
However, none of theses solutions worked, which raised the questions if there is some sort of configuration issue.
Using Inversify / Inversify-React-Decorators / Rect.DI
SomeService.ts
import { inject, injectable } from "inversify";
import { TYPES, ITokenProvider, IFileService } from "../injectables";
import { lazyInject, DIContainer } from "../inversify.config";
export class SomeService {
#inject(TYPES.ITokenProvider) private tokenProvider!: ITokenProvider; //Inversify
//#lazyInject(TYPES.ITokenProvider) private tokenProvider!: ITokenProvider;//Inversify-r-d
//#Inject tokenProvider!: TokenProvider; //react-di
(...)
}
inversify.config.ts
import "reflect-metadata";
import { Container } from "inversify";
import getDecorators from "inversify-inject-decorators";
import { TYPES, ITokenProvider, } from "./injectables";
import { TokenProvider } from "./Services/TokenProvider"
const DIContainer = new Container();
DIContainer.bind<ITokenProvider>(TYPES.ITokenProvider).toConstructor(TokenProvider);
const { lazyInject } = getDecorators(DIContainer, false);
export { DIContainer, lazyInject }
injectables.ts
export interface ITokenProvider {
getSomeToken(): Promise<string>
}
TokenProvider.ts
import "reflect-metadata";
import * as microsoftTeams from "#microsoft/teams-js";
import { injectable } from "inversify";
import { ITokenProvider } from '../injectables';
#injectable()
export class TokenProvider implements ITokenProvider {
public constructor() { }
public async getSomeToken(): Promise<string> {
(...)
}
}
App.tsx (used by react-di instead of inversify.config)
#Module({
providers: [
{ provide: AccessTokenProvider, useClass: AccessTokenProvider },
]
})
Errors
React-DI and Inversify won'r resolve the dependency, causing an undefined error for the property.
Inversify decorators causes following error:
TokenProvider.ts:8 Uncaught ReferenceError: Cannot access 'SomeService' before initialization
at Module.SomeService (VM8 main.chunk.js:248)
at Module../src/inversify.config.ts (inversify.config.ts:11)
(...)
Config
tsconfig.json
{
"include": [
"src/*"
],
"compilerOptions": {
"target": "es5",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"types": [ "reflect-metadata" ]
}
}
I also tried moving the "reflect-metadata" around different classes.
Nested #lazyInject not working :https://github.com/inversify/InversifyJS/issues/941
I have a simple app built in CRA v3.2.0. I use TypeScript with the default settings (see tsconfig.ts below). In /src/sounds/ I have a mp3 file "click_hi.mp3" that I want to use in a component, but I can't import the mp3 with the error Cannot find module 'sounds/click_hi.mp3'.ts(2307).
I tried putting the file in the same folder as the component to be sure to avoid typos in the path. But no luck... How can I import the mp3 file?
App.tsx
import React, { useState, useRef, useEffect } from "react";
import ReactDOM from "react-dom";
import { Sampler } from "tone";
import ClickHi from 'sounds/click_hi.mp3'
export default function ExercisePage() {
const [isLoaded, setLoaded] = useState(false);
const sampler = useRef(null);
useEffect(() => {
sampler.current = new Sampler(
{ "A1": ClickHi },
{
onload: () => {
setLoaded(true);
}
}
).toMaster();
}, []);
const handleClick = () => sampler.current.triggerAttack("A1");
return (
<div>
<button disabled={!isLoaded} onClick={handleClick}>
start
</button>
</div>
);
}
tsconfig.ts
{
"compilerOptions": {
"baseUrl": "src",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["src"]
}
For anybody still having this issue, and just like me, does not want to place the assets in the public folder, do it like this, using "default":
const path = require('../assets/audio/some_audio.mp3');
setAudio(new Audio(path.default));
Note: I only have had this problem using TypeScript. You need to declare a module for mp3, by adding to your project src folder a file named something like "audio.d.ts" and content like declare module '.*mp3';
Example of simple app working, using this: https://geocarlos.github.io/leiamos/
I fixed it by placing the audio file in the public folder and referencing it like this:
useEffect(() => {
sampler.current = new Sampler(
{ A1: `${process.env.PUBLIC_URL}/audio/click_hi.mp3`},
() => {
setLoaded(true);
}
).toMaster();
}, []);
I'm trying to import an .svg file as a React component with TypeScript.
According to the React docs, this is done like so:
import { ReactComponent as Icon } from './Icon.svg';
Following the TypeScript docs, I've added this:
// custom.ts.d
declare module '*.svg' {
const content: any;
export default content;
}
and
// tsconfig.json
{
...
"files": [
"custom.d.ts"
]
}
The SVG is rendering. But I'm getting a TypeScript error:
[ts] Module '"*.svg"' has no exported member 'ReactComponent'. [2305]
Here is my full tsconfig file if that helps:
{
"compileOnSave": false,
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": true,
"outDir": "./dist",
"strict": true,
"jsx": "react",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true,
"skipLibCheck": true,
"esModuleInterop": true,
"baseUrl": ".",
"plugins": [
{
"name": "typescript-styled-plugin"
}
],
"typeRoots": ["./node_modules/#types"],
"lib": ["dom", "es2015", "es2017"]
},
"exclude": ["node_modules", "dist"],
"files": [
"custom.d.ts"
]
}
Thank you!
You have export default content; But you are doing a named import (not a default import).
Fix
Change declaration to export the name you are importing:
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
Additional
Recommend not using files in tsconfig.json. Instead just use include
2019 In addition to #basarat's answer: React.SFC is depracated now consider using React.FunctionComponent like:
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
You're naming the custom types as custom.ts.d and it should call custom.d.ts once the ts compiler is configured to process ts|tsx extensions.
After that, you should be able to reference it into your tsconfig.json include section just like this:
"include": ["custom.d.ts"]
Pull request link
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
Just because it was helpful to me and somewhat related. If you're getting an error with Jest, check this out