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>
Related
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;
**
I am new to React and Typescript, I am trying to add dark-mode to my project,
I created globalStyle component, Themes component and using Themeprovider.
I am facing an issue on my globalStyle component when it says:
property 'body' does not exist type 'DefaultTheme'
My globalStyles.tsx code is as follow:
import { createGlobalStyle} from "styled-components"
export const GlobalStyles = createGlobalStyle`
body {
background: ${({ theme }) => theme.body};
color: ${({ theme }) => theme.text};
font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif;
transition: all 0.50s linear;
}`
my Themes.tsx:
export const lightTheme = {
body: '#FFF',
text: '#363537',
background: '#363537',
}
export const darkTheme = {
body: '#363537',
text: '#FAFAFA',
background: '#999',
}
and my Themeprovider code on App.tsx:
<ThemeProvider theme={this.state.theme === 'light' ? lightTheme : darkTheme}>
<>
<GlobalStyles/>
<ul className='tickets'>
{filteredTickets.map((ticket) => (
<li key={ticket.id} className={ticket.toggle ? 'expand' : 'ticket'}>
<h5 className='title'>{ticket.title}</h5>
<button onClick={() => this.onHide(ticket.id)}>Hide</button>
<p className={ticket.toggle ? 'show-more' : 'content'}>{ticket.content}</p>
<button onClick={()=> this.onToggle(ticket.id)}>{ticket.toggle ? 'Show less' : 'Show more'}</button>
<footer>
<div className='meta-data'>By {ticket.userEmail} | { new Date(ticket.creationTime).toLocaleString()}</div>
</footer>
</li>))}
</ul>
</>
</ThemeProvider>
What am I doing wrong and why theme.body and theme.text is not recognized on globalStyles.tsx?
Thanks !
I'm basing this answer on the following link: https://spectrum.chat/styled-components/general/i-cant-use-my-theme-in-createglobalstyle-function-styled-components-v4-react-v16-6-3~0978b404-ab71-45c9-8f75-0862abde4eb5
createGlobalStyle can accept a shape for the theme:
createGlobalStyle<{theme: ThemeType}>
From the styled-components docs, there's this (https://styled-components.com/docs/api#typescript):
declare module 'styled-components' {
export interface DefaultTheme {
borderRadius: string;
colors: {
main: string;
secondary: string;
};
}
}
So, I suggest you set up an interface for your theme, as above, and then pass it into createGlobalStyle in place of ThemeType
So the answer above fails, as useTheme does not know what type you passed to createGlobalStyles.
But this is a typescript workaround that doesn't require you to use ts-ginore:
As jnpdx suggested, you do need to type the createGlobalTheme object:
createGlobalStyle<{theme: ThemeType}>
The only working solution I have figured out so far is to post-type your useTheme variable like so:
const theme = useTheme() as ThemeType;
Based on the styled-components docs (https://styled-components.com/docs/api#typescript) I created an interface for the body type:
export interface DefaultTheme {
body: string;
}
export const GlobalStyle = createGlobalStyle<{ theme: DefaultTheme }>`
body{
background-color: ${({ theme }) => theme.body};
color: var(--font-color);
}
`;
This works pretty well for me.
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">
I'm writing a new React UI component library using styled-components and styled-system. This library will be used on a side project and should be published as a npm library.
I'm creating a button component and considering almost every component should have a font-family Roboto like this:
const BaseButton = styled.div`
font-family: 'Roboto', sans-serif;
`;
Considering that each component is independent from each other, where is the best place to set a default font-family once for my entire component library?
Thank you
If you want mostly all your components to use Roboto you should set the #font-face up globally.
import { createGlobalStyle } from "styled-components";
import Roboto from './Roboto.otf';
import SecondaryFont from './SecondaryFont.otf';
const GlobalStyles = createGlobalStyle`
#font-face {
font-family: 'Roboto';
src: url('${Roboto}') format('opentype');
}
#font-face {
font-family: 'SecondaryFont';
src: url('${SecondaryFont}') format('opentype');
}
body {
font-family: 'Roboto', sans-serif;
}
`
const YourCustomProvider = ({ children }) => (
<>
<GlobalStyles />
{children}
</>
)
// Inform users to wrap their app with your provider
const App = () => {
return (
<YourCustomProvider>
// Their app
</YourCustomProvider>
)
}
Then to use the secondary font on specific components.
const RandomComponent = styled.div`
font-family: "SecondaryFont"
`
I am using the awesome "Styled-Components"
but I am now using another package that wraps an element inside it so I can't push my StyledComponents there as I don't want to change his package.
I saw glamor has a nice trick.
Is that supported with StyledComponents?
import { css } from 'glamor';
let rule = css({
color: 'red',
})
<div {...rule}>
zomg
</div>
If you think about why I need it, here is an example:
this is an external package I'm using:
External = props => (
<div>
<input style={props.inputStyle} className={props.inputClass} />
</div>
);
so you can see I need to pass in a json style or className
so Glamor will work here, but I dont want to use it just for this scenario.
I'm already enjoying StyledComponent
Thanks
If I understood your query, you can define css rules to a component, like this
import styled from 'styled-components'
const Wrapper = styled.div`
color: 'red';
font-weight: bold;
background-color: ${ props => props.color === 'primary' ? 'green' : 'red' }
`
export const Component = () => {
<Wrapper color='primary'>
I have a red text, and bold font-weight.
</Wrapper>
}