I'm creating a React component library using the TSDX react-with-storybook template. However, I can't seem to get CSS to work in my components via import.
Here is a my button component:
import React, { FC, HTMLAttributes } from 'react';
import './button.css';
export interface ButtonProps extends HTMLAttributes<HTMLButtonElement> {
text: string;
}
export const Button: FC<ButtonProps> = ({ text }) => {
return <button className="button">{text.toLowerCase()}</button>;
};
Here is my css:
.button {
background: '#97C339';
border-radius: '30px';
color: 'white';
border: 'none';
cursor: 'pointer';
font-size: '18px';
height: '60px';
width: '180px';
}
When viewing my button story in the browser the button has no styling and shows 'invalid property value':
What are the best practises in terms of applying css to a react based library?
Here is my package.json:
"devDependencies": {
"#babel/core": "^7.15.8",
"#size-limit/preset-small-lib": "^6.0.2",
"#storybook/addon-essentials": "^6.3.10",
"#storybook/addon-info": "^5.3.21",
"#storybook/addon-links": "^6.3.10",
"#storybook/addons": "^6.3.10",
"#storybook/react": "^6.3.10",
"#types/react": "^17.0.28",
"#types/react-dom": "^17.0.9",
"babel-loader": "^8.2.2",
"husky": "^7.0.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-is": "^17.0.2",
"rollup-plugin-postcss": "^4.0.1",
"size-limit": "^6.0.1",
"tsdx": "^0.14.1",
"tslib": "^2.3.1",
"typescript": "^4.4.3"
}
Not a problem with your React environment, its just that your css is invalid.
Theres no need to encapsulate your css property values in ticks (there are some occasions you need ticks, but none of your's need em).
.button {
background: #97C339;
border-radius: 30px;
color: white;
border: none;
cursor: pointer;
font-size: 18px;
height: 60px;
width: 180px;
}
Removing the ticks should do the trick.
Related
I'm making a little ticker animation for my navbar but for some reason, the ticker doesn't move when I click on a NavLink. At first, I thought it was a problem with the CSS file but that seems to be working fine. I then tried using an older version of react-router-dom but that also didn't seem to work. Some help would be appreciated.
As you can see, the 'active-nav' class is supposed to change to any NavLink that is Active & the rest are left with empty quotation marks.
Navbar.jsx:
import {Link, NavLink} from 'react-router-dom'
import {links} from '../data'
import {GoThreeBars} from 'react-icons/go'
import Logo from '../images/logo.png'
import "./navbar.css"
const Navbar = () => {
return (
<nav>
<div className='container nav__container'>
<Link to="/" className='logo'>
<img src={Logo} alt="Nav Logo"/>
</Link>
<ul className="nav__links">
{
links.map(({name, path}, index) => {
return (
<li>
<NavLink to={path} className={({isActive}) => isActive ? 'active-nav' : ''}>{name}</NavLink>
</li>
)
})
}
</ul>
<button className="nav__toggle-btn">
<GoThreeBars />
</button>
</div>
</nav>
)
}
export default Navbar
Here you can see that most of the functionality is in the CSS
navbar.css:
nav {
height: 5rem;
width: 100vw;
background: var(--color-primary);
display: grid;
place-items: center;
position: fixed;
top: 0;
left: 0;
z-index: 99;
}
/* only shows on medium and small screens */
.nav__toggle-btn {
display: none;
}
.nav__container {
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
width: 1920px;
}
.logo {
width: 7rem;
margin-right: 400px;
}
.nav__links {
display: flex;
gap: 3.5rem;
}
.nav__links a {
transition: var(--transition);
}
.nav__links a:hover {
color: var(--color--secondary);
}
.active-nav {
position: relative;
}
.nav__links::after {
content: '';
display: block;
width: 1.2rem;
height: 1.2rem;
background: var(--color-primary);
position: absolute;
left: calc(50% - 0.6rem);
transform: rotate(45deg);
margin-top: 2.7rem;
}
package.json
{
"name": "reactappblue",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.6.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
app.js:
import {BrowserRouter, Routes, Route} from 'react-router-dom'
import Home from './pages/home/Home'
import About from './pages/about/About'
import Contact from './pages/contact/Contact'
import Gallery from './pages/gallery/Gallery'
import Plans from './pages/plans/Plans'
import Trainers from './pages/trainers/Trainers'
import NotFound from './pages/notfound/Notfound'
import Navbar from './components/Navbar'
import {BrowserRouter as Router} from 'react-router-dom'
const App = () => {
return (
<BrowserRouter>
<Navbar />
<Routes>
<Route index element={<Home/>} />
<Route path="about" element={<About/>} />
<Route path="contact" element={<Contact/>} />
<Route path="gallery" element={<Gallery/>} />
<Route path="plans" element={<Plans/>} />
<Route path="trainers" element={<Trainers/>} />
<Route path="*" element={<NotFound/>} />
</Routes>
</BrowserRouter>
)
}
export default App
It's rather hard to exactly reproduce your problem since you are missing some relevant information in your question. I made some assumptions:
Your package.json would have been valuable since it contains the versions of the packages you're using, I used "react": "18.2.0" and "react-router-dom": "6.4.2"
I wrapped the Navbar in a react-router-dom BrowserRouter in the parent component like this:
import Navbar from './Navbar.jsx';
import {BrowserRouter as Router} from 'react-router-dom'
function App() {
return (
<Router>
<div className="App">
<Navbar/>
</div>
</Router>
);
}
Doing so, the class name was set properly for me. I didn't have to change any parts of the code you provided.
I hope this already helps, if not, please provide the versions of the packages you're using and how the <Navbar /> component is instantiated in its parent component(s).
You can simply use activeClassName prop.
<NavLink to={path} activeClassName="active-nav">{name}</NavLink>
If you are using className you don't need to destructure {isActive}, simply use
<NavLink
to={path}
className={isActive => isActive ? 'active-nav' : ''}
>
{name}
<NavLink/>
I have a React/Django app that's behaving differently when built for production that it does when run on the development server. The development version is how I want it to look.
There are a number of issues with the CSS. Text is a different font, and a some Bootstrap/Reactstrap features are ignored. See example screenshots below.
I think the issue has to do with the order in which css files are processed by the dev server, versus how Django serves the built app, by collecting the files in the /build dir created by the build script into the Django /staticfiles dir. I'm mystified how this would selectively apply classes to the same component, however. (See below - the offset of the jumbotron text is different, while the column size is the same)
Here's a screenshot of the home page in the production build, either served locally by Django or remotely on Heroku. (npm run build or npm run build-local - see package.json file below)
And here is how it looks on the local dev server: (npm run start)
In particular, the offset-md-5 class is ignored on the production build, while the rest of the classes aren't, col-md-5 for example applies in both versions.
Here's the relevant component:
const Photojumbo = () => {
return(
<Container className="jumbo-text ">
<Jumbotron className="" style={{ backgroundImage: "url(/static/photosquat-cropped.jpg)", backgroundSize: 'cover' }}>
<Col className="header header-text col-md-5 offset-md-6" >
<h3>ytterblog</h3>
<p>A blog app and portfolio project by Gabriel Ytterberg</p>
</Col>
</Jumbotron>
</Container>
)
}
Here's the part of my package.json with the build scripts and dependencies. Note that I added the build-local script to emulate how it would look deployed to Heroku, since the deploy process takes so long. The build-local and Heroku build version are identical as far as I can tell.
"dependencies": {
"#testing-library/jest-dom": "^5.11.5",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"axios": "^0.21.0",
"bootstrap": "^4.5.3",
"bootstrap-social": "^5.1.1",
"express": "^4.17.1",
"font-awesome": "^4.7.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-fontawesome": "^1.7.1",
"react-redux": "^7.2.2",
"react-redux-form": "^1.16.14",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.0",
"react-transition-group": "^4.4.1",
"reactstrap": "^8.7.1",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"web-vitals": "^0.2.4"
},
"scripts": {
"start": "PUBLIC_URL=http://localhost:3000/ react-scripts start",
"build": "PUBLIC_URL=https://ytterblog.herokuapp.com/ react-scripts build",
"build-local": "PUBLIC_URL=http://localhost:8000/ react-scripts build && python manage.py collectstatic --noinput",
"postbuild": "python manage.py collectstatic --noinput",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
Here's my App.css, which is the only css file I'm using:
height: 40vmin;
pointer-events: none;
}
#media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
#keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.jumbotron {
position:relative;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
margin: 0 auto;
background: none;
color:floralwhite;
}
.navbar-dark {
background-color: #142f87;
}
.header{
background-color: #1a3db0;
margin:0px auto;
padding: 20px 0px 20px 0px;
}
.header-text{
color: #dbdbdb;
text-align: center;
}
.footer{
background-color: #1a3db0;
margin-top: 50px;
padding: 20px 0px 20px 0px;
position: relative;
}
.footer-text{
color: #dbdbdb;
text-align: center;
}
.avatar{
height: 100;
width: 100;
margin: 20px;
}
.postcard{
margin: 50px 0px 50px 0px;
}
dl {
display: grid;
grid-template-columns: max-content auto;
column-gap: 20px;
}
dt {
grid-column-start: 1;
}
dd {
grid-column-start: 2;
}
.card {
padding-right: 0!important;
padding-left: 0!important;
}
What am I missing?!?!
It could be race condition. I had an issue where in production, the setState getting called twice, and somehow it run in parallel. The result rendered was half 1st state, and the other half was 2nd state.
I don't remember how did I solve it. Though, you try check if a setState is busy.
Use the developer tools on the browser to see if any bootstrap CDNs or other libraries are not loading properly if any of them are being blocked or ignored somehow it will probably be displayed on the console of the developer tools, that is what I would do.
I currently want to replace /deep/ for ::v-deep or >>> in my Laravel/Vue project because it is deprecated. But the only thing that keeps working is /deep/ the other options does not seem to work. For example I have this styling in my component:
<style scoped>
.v-data-table
>>>
tbody
>>>
tr:hover:not(.v-data-table__expanded__content) {
background: #ffffff !important;
}
.v-data-table >>> tr {
height: 60px;
}
</style>
It only works when I use /deep/, >>> doesn't to anything. I don't know if it has something to do with my used packages or webpack config. I recently updated all my NPM packages, this is my package.json:
"devDependencies": {
"axios": "^0.19.2",
"bootstrap": "^4.0.0",
"cross-env": "^5.1",
"jquery": "^3.2",
"laravel-mix": "^5.0.1",
"lodash": "^4.17.13",
"resolve-url-loader": "^2.3.1",
"sass": "^1.26.3",
"sass-loader": "7.*",
"vue": "^2.5.17",
},
"dependencies": {
"#fortawesome/fontawesome-free": "^5.12.1",
"secure-ls": "^1.2.6",
"vue-i18n": "^8.15.5",
"vue-router": "^3.1.6",
"vuetify": "^2.2.17",
"vuex": "^3.1.3",
"vuex-persistedstate": "^2.7.1"
}
And my webpack.mix.js config:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.options({
postCss: [
require('autoprefixer'),
],
})
What am I currently missing that I can't use the new deep selectors? Any help is appreciated.
Update:
The full component looks like this:
<template>
<v-data-table
:headers="headers"
:items="items"
:disable-sort="true"
:item-key="itemKey"
:disable-pagination="true"
:hide-default-footer="true"
:search="search"
>
<template v-for="slot in Object.keys($scopedSlots)" :slot="slot" slot-scope="scope">
<slot :name="slot" v-bind="scope" />
</template>
</v-data-table>
</template>
<script>
export default {
name: "BaseDataTable",
props: {
headers: Array,
items: Array,
itemKey: {
type: String,
default: "id"
},
search: {
type: String,
required: false
}
}
};
</script>
<style scoped>
.v-data-table
/deep/
tbody
/deep/
tr:hover:not(.v-data-table__expanded__content) {
background: #ffffff !important;
}
.v-data-table /deep/ tr {
height: 60px;
}
</style>
I meet this problem in the Mpvue Or the Uniapp.
I fixed it finally by adding an option. But I am not sure it's suited for Vue projects. You can try it.
options: { styleIsolation: 'shared' }, // add this
methods: {
yourFunc1 () {
}
}
I have a carousel running with Slick and Jquery,
there's overriding style for the slicks dots (defined in the component)
However when running on localhost I can't see the slicks dots receive the CSS, it just loaded from the default slick css.
I checked the internal stylesheet rendered on the web: the default slick.css & slick-theme.css loaded before the component's css so it's supposed the component should have overridden the style but it's not working ?
Here is what I export in Angular.json
"styles": [
"src/styles.scss",
"node_modules/bulma/css/bulma.min.css",
"node_modules/slick-carousel/slick/slick-theme.css",
"node_modules/slick-carousel/slick/slick.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/slick-carousel/slick/slick.min.js"
],
In my component SCSS:
#import "../../shared_scss/mixin.scss";
#import "../../shared_scss/variables.scss";
/* Slider */
.carousel{
background-size: cover;
height: auto;
margin-top: 50px;
margin-bottom: 0 !important;
.carousel_item{
&:hover{
cursor: pointer;
}
}
.slick-dots{
bottom: 40px;
li button:before{
font-size: 20px;
}
li.slick-active button:before {
opacity: .75;
color: $neon-green;
}
}
}
// responsive homepage carousel
#include breakpoint(xs){
.carousel{
margin-top: 40px;
.slick-dots{
bottom: 5px
}
}
}
My component ts file :
import { Component, OnInit, AfterViewInit } from '#angular/core';
import * as $ from 'jquery';
import 'slick-carousel';
#Component({
selector: 'app-slider',
templateUrl: './slider.component.html',
styleUrls: ['./slider.component.scss']
})
export class SliderComponent implements OnInit, AfterViewInit {
ngAfterViewInit(): void {
// Slick carousel
$('.carousel').slick({
slidesToShow: 1,
adaptiveHeight: true,
arrows: false,
dots: true,
infinite: true,
speed: 300
});
}
constructor() { }
ngOnInit() {
}
}
Can you change the order of css/scss files angular.json as follow
"styles": [
"node_modules/bulma/css/bulma.min.css",
"node_modules/slick-carousel/slick/slick-theme.css",
"node_modules/slick-carousel/slick/slick.css",
"src/styles.scss",
],
and instead of applying style in component level, put the style inside style.scss, which will apply globally. Hence it will override the plugin style.
So I'm just starting to learn React and I'm trying to incorporate a css file to style a react component (ie a sidebar) but I'm not sure why none of the styles show up on the webpage. I've tried inlining css in the index.js file and that works but I'm trying to move all of the styling code into a css file. I have a sass loader and css loader installed and included them in the webpack.config.js file. Am I just forgetting something dumb?
Here's my style.css file
.sidebar {
position: fixed;
height: 200px;
font-size: 20;
width: 60px;
background-color: deepskyblue;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 200px;
background-color: azure;
}
li {
display: block;
color: gray;
padding: 8px;
font-size: 20;
text-decoration: none;
}
li :hover {
background-color: forestgreen;
}
And my index.js file
import React from 'react'
import {styles} from './style.css'
import Home from './home.js'
export class Sidebar extends React.Component {
render() {
return (
<div className={styles.sidebar}>
<ul>
<li>Home</li>
<li>Test1</li>
<li>Test2</li>
</ul>
</div>
)
}
}
no need to call styles.sidebar as if it were an object, just import the file and assign className as an ordinary class....
import './style.css';
// [...]
<div className='sidebar'>
You mentioned you have CSSLoader in your webpack.config.js file. First, let's confirm that you have something similar to me:
{
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" }
]
}
]
}
}
Now, every time you run your webpack server, the dev bundle will include your styles in it. With that, you should be able to import css files my referencing them in the React file:
import './MyComponent.css'
const MyComponent = () => {...};
If everything is still the same, but things are still not working, I highly recommend create-react-app, which is a painless solution for you to focus on learning React without bothering so much with configuration details. Create React app includes amongst other things, CSS importing and Jest testing.