I have a Material UI theme like so:
import { createMuiTheme } from '#material-ui/core/styles'
const primaryColor = '#009baa'
const theme = createMuiTheme({
typography: {
fontFamily: ['custom font here'].join(','),
h1: { color: primaryColor },
h2: { color: primaryColor, fontSize: '26px' },
},
palette: {
primary: {
main: primaryColor,
},
},
overrides: {
MuiButton: {
root: {
background: primaryColor,
textTransform: 'none',
},
},
},
})
export default theme
used in my main app like so:
...
<ThemeProvider theme={theme}>
<Provider store={store}>
<Calendar />
</Provider>
</ThemeProvider>
...
I than have a calendar.stories.js like so:
import { storiesOf } from '#storybook/react'
import { CalendarComponent } from "./Calendar"
import { formatAvailabilitiesData } from '../../__mocks__/availabilities'
import { log } from 'util';
import {muiTheme} from 'storybook-addon-material-ui'
import theme from '../../theme'
const props = {
selectedAvailablity: formatAvailabilitiesData[0],
selectedDate: new Date('2019-07-24T07:00:00.000Z'),
dateClick: () => null,
}
storiesOf("Calendar", module)
.addDecorator(muiTheme([PeabodyTheme]))
.add("Basic", () => (
<CalendarComponent {...props} />
))
and webpack file for storybook like so:
const path = require('path');
// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
// `mode` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// Make whatever fine-grained changes you need
config.module.rules.push(
{
test: /\.(ttf|eot|svg)(\?[a-z0-9#=&.]+)?$/,
loaders: ["file-loader"]
});
// Return the altered config
return config;
};
The fonts are being displayed correctly in the application but not in the storybook. I have tried to import some local css and everything apart from font-family works, which makes think that is something to do with the loading of the fonts. No error either in the console.
UPDATE
I have even tried to import CSS directly inside my component like so:
#font-face {
font-family: 'Poppings';
src: url('../../assets/fonts/Poppins-Regular.ttf')
}
h2 {
font-family: 'Poppings';
}
and although this time the font is actually loaded in the network tab the storybook component h2 doesn't inherit the custom font....
I suggest the following:
If these are local fonts, otherwise ignore: Create a css file for fonts, in which you only define the #font-face for your fonts.
Create a file preview-head.html where your Storybook configurations are, ie, .storybook.
In this file, add a line each for the css files containing font-face definitions in a link tag, such as:
<!-- local fonts -->
<link rel="stylesheet" href="./fonts/fonts.css" />
<!-- external font (I just copied the code for a random font from Google -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Castoro:ital#1&display=swap" rel="stylesheet">
Related
In most examples, to disable prefetching, they do so by disabling a specific link for prefetching, see the following example:
<Link href="/about" prefetch={false}>
<a>About us</a>
</Link>
I want to set prefetch to false for the whole project.
Are there settings for this in the next.config.js file?
How should I do this?
Unfortunately, it's not supported in Next.js to disable prefetch globally.
The first workaround
create a Babel plugin local to your project which adds prefetch={false} everywhere we use <Link /> from 'next/link'.
/**
* Based on the docs at https://nextjs.org/docs/api-reference/next/link, the
* only way to disable prefetching is to make sure every <Link /> has <Link
* prefetch={false} />
*
* We don't want to create a wrapper Component or go around changing every
* single <Link />, so we use this Babel Plugin to add them in at build-time.
*/
module.exports = function (babel) {
const { types: t } = babel
return {
name: 'disable-link-prefetching',
visitor: {
JSXOpeningElement(path) {
if (path.node.name.name === 'Link') {
path.node.attributes.push(
t.jSXAttribute(
t.jSXIdentifier('prefetch'),
t.JSXExpressionContainer(t.booleanLiteral(false)),
),
)
}
},
},
}
}
Add/modify ./.babelrc to load your local plugin:
{
"presets": ["next/babel"],
"plugins": ["./babel/disable-nextjs-link-prefetching"]
}
The Second workaround
Create a custom link component and use prefetch={false} for it and use it instead of using the next/link directly.
import Link from 'next/link'
export default function MyLink(props) {
// defaults prefetch to false if `prefetch` is not true
return <Link {...props} prefetch={props.prefetch ?? false}>
}
Resource
I have tried a lot of different ways to do this, with absolutely zero luck, over multiple days.
I am trying to use Solito Nativebase Universal Typescript repo to do this:
https://github.com/GeekyAnts/nativebase-templates/tree/master/solito-universal-app-template-nativebase-typescript
I have read, and tried everything on this page at least a dozen times:
https://github.com/GeekyAnts/nativebase-templates/issues/43
My current next.config.js file looks like this:
/** #type {import('next').NextConfig} */
const { withNativebase } = require('#native-base/next-adapter')
const withImages = require('next-images')
const { withExpo } = require('#expo/next-adapter')
const withFonts = require('next-fonts')
module.exports = withNativebase({
dependencies: [
'#expo/next-adapter',
'next-images',
'react-native-vector-icons',
'react-native-vector-icons-for-web',
'solito',
'app',
],
plugins: [
[withFonts, { projectRoot: __dirname }],
withImages,
[withExpo, { projectRoot: __dirname }],
],
nextConfig: {
images: {
disableStaticImages: true,
},
projectRoot: __dirname,
reactStrictMode: true,
webpack5: true,
webpack: (config, options) => {
config.resolve.alias = {
...(config.resolve.alias || {}),
'react-native$': 'react-native-web',
'#expo/vector-icons': 'react-native-vector-icons',
}
config.resolve.extensions = [
'.web.js',
'.web.ts',
'.web.tsx',
...config.resolve.extensions,
]
return config
},
},
})
I have also tried using #native-base/icons, again, no luck.
My end use case is this:
export const Cart = (props: IIconStyles) => {
return (
<Icon
as={FontAwesome5}
name="shopping-cart"
size={props.size ? props.size : 6}
color="gray.200"
/>
)
Theoretically it SHOULD show a shopping cart, but instead, this is what I see:
So clearly there's some font issue or other issue that is preventing it from loading in the actual SVG.
I can't figure out what this is - I've tried rewriting my _document.tsx file like this:
https://docs.nativebase.io/nb-icons
I've tried adding this to my next.config.js:
config.module.rules.push({
test: /\.ttf$/,
loader: "url-loader", // or directly file-loader
include: path.resolve(__dirname, "node_modules/#native-base/icons"),
});
When I try to do something like this:
import fontsCSS from '#native-base/icons/FontsCSS';
in my _document.tsx file, I get the following error:
Module not found: Can't resolve '#native-base/icons/lib/FontsCSS'
Despite the fact that I've got #native-base/icons installed in my package.json, as well as having it in my Babel file per the instruction link above.
How do I get vector icons to work in Next?
Note, this is specifically Next/Expo/React Native
You can read more about setup of next-adapter-icons here.
I got it working with following approach,
next.config.js
const { withNativebase } = require("#native-base/next-adapter");
const path = require("path");
module.exports = withNativebase({
dependencies: ["#native-base/icons", "react-native-web-linear-gradient"],
nextConfig: {
webpack: (config, options) => {
config.module.rules.push({
test: /\.ttf$/,
loader: "url-loader", // or directly file-loader
include: path.resolve(__dirname, "node_modules/#native-base/icons"),
});
config.resolve.alias = {
...(config.resolve.alias || {}),
"react-native$": "react-native-web",
"react-native-linear-gradient": "react-native-web-linear-gradient",
"#expo/vector-icons": "react-native-vector-icons",
};
config.resolve.extensions = [
".web.js",
".web.ts",
".web.tsx",
...config.resolve.extensions,
];
return config;
},
},
});
pages/_document.js
import React from 'react';
import { DocumentContext, DocumentInitialProps } from 'next/document';
import { default as NativebaseDocument } from '#native-base/next-adapter/document'
// Icon Font Library Imports
import MaterialIconsFont from '#native-base/icons/FontsCSS/MaterialIconsFontFaceCSS';
import EntypoFontFaceCSS from '#native-base/icons/FontsCSS/EntypoFontFaceCSS';
const fontsCSS = `${MaterialIconsFont} ${EntypoFontFaceCSS}`;
export default class Document extends NativebaseDocument {
static async getInitialProps(ctx) {
const props = await super.getInitialProps(ctx);
const styles = [
<style key={'fontsCSS'} dangerouslySetInnerHTML={{ __html: fontsCSS }} />,
...props.styles,
]
return { ...props, styles: React.Children.toArray(styles) }
}
}
pages/index.tsx
import React from "react";
import { Box, Icon } from "native-base";
import Entypo from "#expo/vector-icons/Entypo";
export default function App() {
return (
<Box>
<Icon
as={Entypo}
name="user"
color="coolGray.800"
_dark={{
color: "warmGray.50",
}}
/>
</Box>
);
}
Using import like this:
import MaterialIcons from '#expo/vector-icons/MaterialIcons'
in place of:
import { MaterialIcons } from '#expo/vector-icons'
worked for me. I think this is because of the way babel/webpack handles imports in the template. I followed the steps here to setup the icons.
Here's what that looks like on web:
I am creating a custom UI library for work that uses Material-UI. The UI library has a custom theme where I added to the palette object with custom company colors. The theme lives in the UI library, and for elements that live there, I can use the custom colors in makeStyles, but when I try to use the exported theme in the main codebase, the custom colors throw errors in makeStyles.
I believe the issue is I'm not exporting the theme's custom module. I am unsure how to export and import this correctly into the main codebase. Currently, I am only exporting the theme file and importing it into the main codebase.
Main Codebase:
import { theme } from 'customUILibrary';
...
<MuiThemeProvider theme={theme}>
...
</MuiThemeProvider>
CustomUILibrary:
index.ts:
export { theme } from 'theme/theme';
theme/theme.ts
import {
createTheme,
responsiveFontSizes,
} from '#material-ui/core/styles';
import './extendPalette';
export const theme = responsiveFontSizes(createTheme({
palette: {
gradients: {
primary: 'linear-gradient(270deg, #35C7E1 -10.76%, #1A92BD 121.8%)',
secondary: 'linear-gradient(270deg, #194E94 0%, #317CA6 100%)',
},
},
}));
extendPalette.ts
declare module '#material-ui/core/styles/createPalette' {
export interface PaletteOptions {
gradients: {
primary: string
secondary: string,
},
}
export interface Palette {
gradients: {
primary: string
secondary: string,
},
}
}
The custom theme attributes work great inside the UI Library with the UI elements, but when imported into the main codebase the custom attributes aren't being picked up, and in fact causing errors.
As suggested here, you can do something like this:
declare module "#mui/material/styles" {
interface Palette {
custom: {
pink: string;
};
}
interface PaletteOptions {
custom: {
pink: string;
};
}
}
Then you can set you value in theme safely:
const theme = createTheme({
palette: {
custom: {
pink: "pink"
}
}
});
and use it in styles:
<Button sx={{ color: "custom.pink" }}>Content</Button>
See my codesandbox example
I am a beginner in material react. I used a palette in the theme in my code, but it shows me a different color code when it displays. please guide me
theme code
import {createMuiTheme} from "#material-ui/core";
const primaryColor="#FF4D23";
const Theme = createMuiTheme({
overrides: {
MuiTypography: {
root: {
fontFamily: "shabnam !important",
}
},
palette:{
primary:{
main:primaryColor,
}
}
}
});
export default Theme;
style code
LogoText:{
color:theme.palette.primary.main,
fontSize:'23px ',
fontWeight:600,
marginRight:'10px'
},
But it shows
**
color: #3f51b5;
**
Working with Chakra for the first time and trying to change the default font to Times New Roman in Chakra UI but get no effect.
Did an import, assigned new theme, passed it as props to ChakraProvider but nothing happens in code
index.js
import {extendTheme, ChakraProvider} from "#chakra-ui/react"
const customTheme = {
fonts: {
body: 'Times New Roman, sans-serif',
heading: 'Times New Roman, sans-serif',
mono: 'Times New Roman, sans-serif', }
const theme = extendTheme({customTheme})
ReactDOM.render(
<React.StrictMode>
<ChakraProvider theme={theme}>
<App/>
</ChakraProvider>
</React.StrictMode>,
document.getElementById('root')
);
My text component doesn't seem to change
import {Text} from '#chakra-ui/react'
<Text> Some text </Text>
You can see how to do this on their docs.
Create a theme.js file where we will override the default theme
Inside of here add the following:
// importing the required chakra libraries
import { theme as chakraTheme } from '#chakra-ui/react'
import { extendTheme } from "#chakra-ui/react"
// declare a variable for fonts and set our fonts. I am using Inter with various backups but you can use `Times New Roman`. Note we can set different fonts for the body and heading.
const fonts = {
...chakraTheme.fonts,
body: `Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"`,
heading: `Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"`
}
// declare a variable for our theme and pass our overrides in the e`xtendTheme` method from chakra
const customTheme = extendTheme(overrides)
// export our theme
export default customTheme
Wrap our app in the theme
// import our theme
import theme from '../customTheme.js'
// wrap our application with the theme. This can be passed onto the ChakraProvider.
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>
I can see that your extendTheme usage is wrong.
const theme = extendTheme({customTheme}) the curly brackets shouldn't be there. This essentially translates to:
const theme = {
customTheme: { // <-- it adds the custom theme as a customTheme property
fonts: {
...
}
}
}
Just remove the curly brackets and you're good to go!
This works for me using chakra and nextjs.
create a file styles.css with
#font-face {
font-family: "Font";
src: url('../your/path/Font.woff');
font-weight: normal;
font-style: normal;
}
in your index.js
import '../path/styles/styles.css'
Last version:
const overrides = extendTheme({
styles: {
global: (props: StyleFunctionProps) => ({
body: {
fontFamily: '"Roboto", "Noto", sans-serif"'
},
}),
},
})
const AppTheme = extendTheme(overrides)
export default AppTheme;
Use:
<ChakraProvider theme={AppTheme}>
<Component {...pageProps} />
</ChakraProvider>