Problem
Need to show less number of pages in mobile view so that it can be aligned with heading (My Orders) in the same line.
Library
material-ui/pagination
Progress
Able to remove Next and Previous content in the mobile view but neither able to find any out-of-the-box prop(s) nor any CSS to reduce number of pages in mobile view
Web view
Mobile View
Code
CSS
#media (min-width: 501px) {
.MuiPagination-root {
.MuiPagination-ul {
flex-wrap: nowrap;
li {
&:first-child {
flex-basis: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
> button::before {
margin-right: 10px;
content: "Previous ";
}
}
&:last-child {
flex-basis: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
> button::after {
margin-left: 10px;
margin-right: 20px;
content: " Next";
}
}
}
}
}
Custom Component
import React, { useState } from "react";
import PropTypes from "prop-types";
import Pagination from '#material-ui/lab/Pagination';
export const CustomPagination = ({ onChange, totalRecords, currentPage, className, shape }) => {
return (
<Pagination
count={totalRecords}
shape={shape}
className={className}
onChange={onChange}
page={currentPage}
/>
)
};
CustomPagination.propTypes = {
paginationLength: PropTypes.number,
selectPage: PropTypes.func,
activePage: PropTypes.number,
};
One of the solutions I came up with is wrapping the component pagination inside a Box then changing its size depending on the view :
export function Test() {
return;
<>
<Box sx={{ display: { xs: "none", md: "block" } }}>
<Pagination
/>
</Box>
<Box sx={{ display: { xs: "block", md: "none" } }}>
<Pagination
size="small"
/>
</Box>
</>;
}
</Box>
Related
I have following react code.
the code
What I would like is to just when I click on "about" menu background color should change from red to blue otherwise stay in red.
in another scenario:
(my problem is how to access to links "route" or "path" in react because i want to add condition like ==> if (path =="./about) do somthing...)
is there any way to do this? i would appreciate for your help.
If you are using react-router-dom
Then you can use the useLocation hook to get the current location
First import it
import { useLocation } from 'react-router-dom';
Then get the location
const location = useLocation();
You can use a useEffect hook to change the background color whenever the location changes
useEffect(()=>
{
if(location.pathname == '/about'){
// Change background color
}
}
},[location])
This should work for you
Try to include this code in your App.js
Following code works:
const Nav = styled.nav`
height: 100px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 0px 10px;
width: 100%;
z-index: 100;
/* background-color: red; */
`;
const Menu = styled.div`
display: flex;
flex-wrap: wrap;
gap: 20px;
align-items: center;
justify-content: center;
`;
const Navbar = ({ toggle }) => {
const [navBg, setNavBg] = React.useState("red");
const location = useLocation();
React.useEffect(() => {
if (window.location.pathname === "/about") {
setNavBg("yellow");
} else {
setNavBg('red')
}
}, [location]);
return (
<Nav style={{ backgroundColor: navBg }}>
<h1 to="/">logo</h1>
<Menu>
<Link to="/">home</Link>
<Link to="/about">about</Link>
<Link to="/services">services</Link>
</Menu>
</Nav>
I am having an issue centring a div with elements using justify-content: space-between;. The child element fills the max-width of the container(900px) prior to either putting a margin auto or justify-content: center; on the parent object. once these styles are added to centre the container the elements inside are crushed to the min-width possible. What's the solution to this because I still would like to have the content inside the container shrink to the screen width?
The parent div using styled-components to have the following styles:
import styled from 'styled-components'
import { ACCOUNT_MAX_WIDTH, UNIT_8 } from '../../../components/_core/grid'
export const AccountMaxWidth = styled.div`
max-width: ${ACCOUNT_MAX_WIDTH};
align-self: stretch;
display: flex;
flex-direction: column;
flex: 1;
padding: ${UNIT_8};
padding-top: 0;
//toggling this on centres the div but crushes the div.
margin: auto;
`
Styles of the child div:
import styled from 'styled-components'
import { COLOUR } from '../../../components/_core/colours'
import { UNIT_1, UNIT_3, UNIT_4 } from '../../../components/_core/grid'
export const PreferencesWrapper = styled.div`
display: flex;
flex-direction: column;
> h2 {
padding: ${UNIT_4} 0;
color: ${COLOUR.primary.blue_slate};
}
`
export const SwitchHeadContainer = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
padding: ${UNIT_1} 0;
> svg {
margin: auto 0;
margin-right: ${UNIT_4};
}
> h4 {
margin: auto 0;
}
`
export const SwitchContainer = styled.div`
display: flex;
flex-direction: column;
> label {
flex-wrap: wrap;
margin: ${UNIT_3} 0;
padding: 0 ${UNIT_1};
justify-content: space-between;
}
Here is the tsx file(this is imported and nested within the AccountMaxWidth styled div):
import { Divider } from '#material-ui/core'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { Switch } from '../../../components/_atoms/Switch'
import { COLOUR } from '../../../components/_core/colours'
import { MailIcon } from '../../../components/_core/icons/Mail'
import { Medium, Small2X } from '../../../components/_core/Typography'
import {
PreferencesWrapper,
SwitchContainer,
SwitchHeadContainer,
} from './index.styles'
export const Preferences = () => {
const { t } = useTranslation()
return (
<PreferencesWrapper>
<Medium>{t('account.preferences.heading')}</Medium>
<SwitchContainer>
<SwitchHeadContainer>
<Small2X>{t('account.preferences.notifications.subheading')}</Small2X>
<MailIcon fill={COLOUR.primary.blue_slate} variant="line" />
</SwitchHeadContainer>
</SwitchContainer>
<SwitchContainer>
<Divider variant="fullWidth" />
<Switch
label={t('account.preferences.notifications.protectionStatus')}
isChecked={true}
onToggle={() => null}
/>
</SwitchContainer>
<SwitchContainer>
<Divider variant="fullWidth" />
<Switch
label={t('account.preferences.notifications.highThreat')}
isChecked={true}
onToggle={() => null}
/>
</SwitchContainer>
<SwitchContainer>
<Divider variant="fullWidth" />
<Switch
label={t('account.preferences.notifications.mediumThreat')}
isChecked={true}
onToggle={() => null}
/>
</SwitchContainer>
<SwitchContainer>
<Divider variant="fullWidth" />
<Switch
label={t('account.preferences.notifications.lowThreat')}
isChecked={true}
onToggle={() => null}
/>
</SwitchContainer>
<SwitchContainer>
<Divider variant="fullWidth" />
<Switch
label={t('account.preferences.notifications.news')}
isChecked={true}
onToggle={() => null}
/>
</SwitchContainer>
<SwitchContainer>
<Divider variant="fullWidth" />
<Switch
label={t('account.preferences.notifications.account.heading')}
isChecked={true}
onToggle={() => null}
/>
</SwitchContainer>
</PreferencesWrapper>
)
}
[Image One][1]
Here is an image where the div is centred using margin auto or align-self centre as you can see the div is crushed.
[Image Two][2]
Here is an image of how the div looks before centre aligning and how I'd like it to look after centre alignment.
The only difference between the two images is a margin auto
[1]: http://imgur.com/hgJUU0a
[2]: http://imgur.com/W2gyAzs
I may need more clarification on your question, but justify-content: space-between; should still keep you element center, especially if it's the only element in its parent, without any sibling elements. To center its own children, I would add the centering properties to that div, like in this code:
Also, make sure that the parent element of the parent is also display: flex or that align-self will not do anything. And for a horizontal stretch, you may actually want to use justify-content: stretch.
.parentElement {
display: flex;
justify-content: space-between;
}
.parentElement > .childElement {
display: flex;
justify-content: center;
flex: 1;
}
I'd like to assist further, but I'm still having a difficult time fully understanding your question. Would you mind adding a working snippet to your ticket that demonstrates the issue that needs to be fixed so I can adjust a copy of your code directly? Thanks!
Try giving the PreferencesWrapper a min-width or width: 100%.
Hope you are doing well, you have not shared any codesandbox to test out the changes on your code and provide you the solution, but what seems to be the problem on the surface is max-width. Please change the styles accordingly.
export const AccountMaxWidth = styled.div`
min-width: ${ACCOUNT_MAX_WIDTH};
align-self: stretch;
display: flex;
flex-direction: column;
flex: 1;
padding: ${UNIT_8};
padding-top: 0;
I'm new to react and css.
My goal here is to center my 3 switches and the name of them in the center of my page. Then I would like the 3 switches button to adjust their position automatically no matter the length of the text on its left.
Here is what I have for the moment.
This is the switch button + text. I made a style to align the text with the middle of the switch icon. I tried the verticalAlign: "middle" but it the text went at the bottom position.
import React, { useState } from "react";
import Switch from "react-switch";
const SwitchMode = ({text}) => {
const [checked, setChecked] = useState(false)
const handleChange = StateCheck => {
setChecked(StateCheck)
}
return(
<div className="switch-position">
<label>
<span style={{display: "inline-flex", verticalAlign: '50%', marginRight: '4%'}}>{text}</span>
<Switch
onChange={handleChange}
checked={checked}
className="react-switch"
/>
</label>
</div>
)
}
export default SwitchMode
And this is the css I've made for the moment
body {
margin: 0;
}
.image-position {
display: flex;
justify-content: center;
width: 100%;
margin-top: 5%;
height: auto;
}
.service-position {
display: flex;
flex-direction: column;
margin-top: 5%;
}
.switch-position {
display: inline;
justify-content: center;
width: 100%;
margin-top: 1%;
}
in this file I create my switch button, apply the css and give them a name.
import React from 'react';
import './index.css';
import ReactRoundedImage from "react-rounded-image";
import Img from './images/Diamond.png'
import SwitchMode from './Switch';
const Profile = () => {
return(
<div>
<div className='image-position'>
<ReactRoundedImage image={Img} roundedSize="0" imageWidth="150" imageHeight="150" />
</div>
<div className='service-position'>
<SwitchMode text="Discord"/>
<SwitchMode text="Google"/>
<SwitchMode text="FEJZIOFZEJ"/>
</div>
</div>
)
}
export default Profile
this is the actual result
You can do something like this:
body {
margin: 0;
}
.image-position {
display: flex;
justify-content: center;
width: 100%;
margin-top: 5%;
height: auto;
}
.service-position {
display: flex;
justify-content: center;
flex-direction: row;
margin-top: 5%;
}
.switch-position {
text-align: center;
width: 100px;
}
and change your SwitchMode component to this:
const SwitchMode = ({ text }) => {
const [checked, setChecked] = useState(false);
const handleChange = (StateCheck) => {
setChecked(StateCheck);
};
return (
<div className="switch-position">
<label>
<span>{text}</span>
<Switch
onChange={handleChange}
checked={checked}
className="react-switch"
/>
</label>
</div>
);
};
The main things I did was set justify-content: center and flex-direction: row on .service-position. To make sure the .switch-position items displayed in a row and were centered.
For centering the text next to the switch button I used text-align: center and to make sure the text is displayed above the switch button I set a fixed with on .switch-position.
Sandbox Example
I have a React component that asks user to upload profile photo. In the same view, the user can see a greyed out 'next' button. When the photo is uploaded and displayed, the user sees a horizontal scrolling bar to adjust photo size that comes between the photo and next button. My goal is to keep the next button in view at all times but also keep all elements of the component in the same order. Right now, a user has to scroll down to see the 'next' once the image is loaded. I've been experimenting with flex and position and even a ternary in the JSX to add paddingBottom when !isLoading. Can someone give a good direction so that the user doesn't have to scroll down to see the next' button?
Here is my component:
import React, { useContext, useState, useEffect } from 'react';
import styled from 'styled-components';
import Typography from 'components/Typography';
// import { useMediaQuery } from 'beautiful-react-hooks';
import { medium } from 'constants/mediaQueries';
import AppButton from 'components/AppButton';
import useFetcher from 'hooks/useFetcher';
import { getMeApi } from 'utils/apiRoutes';
import Loader from 'components/Loader';
import routePaths from 'containers/Router/routePaths';
import { useHistory, useLocation } from 'react-router-dom';
import { UserContext } from 'containers/context/UserContext';
import checkmarkImage from 'assets/images/checkmark.svg';
import { useDispatch } from 'react-redux';
import BackArrowGrid from 'components/Auth/BackArrowGrid';
import UploadImageInput from 'components/UploadImageInput';
import { setPlainLogo, setInitialLogo } from '../../store/header/actions';
// const MOBILE = 250;
// const DESKTOP = 356;
const Container = styled.div`
width: 100%;
position: relative;
align-items: center;
justify-content: flex-end;
display: flex;
flex-direction: column;
border: pink solid 2px;
`;
const ButtonContainer = styled.div`
margin-top: 32px;
display: flex;
align-items: center;
flex-direction: row;
div {
margin-bottom: 16px;
}
img {
margin-left: 8px;
}
`;
const Title = styled(Typography)`
font-size: 40px;
text-transform: uppercase;
margin-bottom: 64px;
#media (min-width: ${medium}) {
margin-bottom: 64px;
}
`;
const ButtonContent = styled.span`
display: flex;
align-items: center;
`;
const Form = styled.div`
width: 100%;
display: flex;
flex-direction: column;
align-self: flex-end;
border: yellow solid 2px;
.empty {
display: none;
}
#media (min-width: ${medium}) {
flex-direction: column;
align-items: center;
min-height: auto;
.empty {
display: block;
width: 118px;
}
}
`;
const UploadPicture = () => {
const { fetcher, error, isLoading } = useFetcher();
const { setUserFromLogin } = useContext(UserContext);
const history = useHistory();
const location = useLocation();
// const isDesktop = useMediaQuery(`(min-width: ${medium})`);
const dispatch = useDispatch();
const [image, setImage] = useState({});
const uploadImage = async () => {
const result = await fetcher({
url: getMeApi,
method: 'POST',
body: {
photo: image.croppedImage.source,
},
});
if (result.errors) {
return;
}
setUserFromLogin(result.user);
if (location.profile) {
history.push(routePaths.Profile);
} else {
history.push(routePaths.Welcome);
}
};
useEffect(() => {
dispatch(setPlainLogo());
return () => dispatch(setInitialLogo());
}, []);
const onPictureChange = newImage => {
setImage(prevImage => ({
...prevImage,
...newImage,
}));
};
return (
<>
<BackArrowGrid>
<Container>
<Title h1>Profile photo</Title>
<Form>
<div className="empty"> </div>
<UploadImageInput
onChange={onPictureChange}
image={image}
placeholder={
"Upload a profile photo. This is how you'll appear to other Color TV users."
}
height={356}
width={356}
horizontalPadding={60}
aspect={1}
round
/>
<ButtonContainer>
{error && (
<Typography error>
Error while uploading the image, please try again.
</Typography>
)}
<AppButton
primary={!!image.croppedImage}
disabled={isLoading || !image.croppedImage}
onClick={uploadImage}
noBorder
>
<ButtonContent>
{isLoading ? (
<Loader className="center" size={30} />
) : (
'Next'
)}
{!isLoading && !!image.croppedImage && (
<img src={checkmarkImage} alt="checkmark_icon" />
)}
</ButtonContent>
</AppButton>
</ButtonContainer>
</Form>
</Container>
</BackArrowGrid>
</>
);
};
export default UploadPicture;
Since this component is part of a larger code base, I'm not sure how to run a snippet of it but here are 2 photos - before and after. Once the photo is uploaded, the next button drops out of view because the slider component is added in. I want to next button to stay in view no matter how the browser size.
I couldn't get a JSFiddle to work properly with React and some other dependencies, so I hope the link to this Github repo is sufficient for demonstrating the issue:
https://github.com/ishraqiyun77/button-issues/
Basically, a group of buttons is rendered and they should be auto-widened to fill white space and take up the whole row. This works in Chrome, Edge, Safari, and Firefox. It looks like this:
This isn't happening in IE. I've been messing with it for hours and haven't made much progress:
Here is the code, although could clone the repo I posted above:
// component.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
Button,
Col,
Modal,
ModalBody,
ModalHeader,
Row
} from 'reactstrap';
import styles from '../assets/scss/app.scss';
class TestPrint extends Component {
constructor(props) {
super(props);
this.state = {
modal: false,
}
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
modal: !this.state.modal
})
}
renderContent() {
let buttons = [];
for (let i = 1; i < 50; i++) {
buttons.push(
<Col key={i}>
<Button
key={i}
className='cuts-btn'
>
{i} - Test
</Button>
</Col>
);
};
return buttons;
}
render() {
return (
<div>
<Button
style={
{
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
}
}
onClick={this.toggle}
>
Open Modal for Buttons
</Button>
<Modal
size='lg'
isOpen={this.state.modal}
toggle={this.toggle}
className='results-modal'
>
<ModalHeader toggle={this.toggle}>
Button Issues
</ModalHeader>
<ModalBody>
<div className='results-bq-cuts'>
<Row>
{this.renderContent()}
</Row>
</div>
</ModalBody>
</Modal>
</div>
)
}
}
ReactDOM.render(<TestPrint />, document.getElementById('app'));
.results-modal {
max-width: 1200px;
.modal-content {
.modal-body {
margin-left: 13px;
margin-right: 13px;
.results-bq-cuts {
width: 100%;
.col {
padding:2px;
}
.cuts-btn {
font-size: 11px;
padding: 3px;
width: 100%;
box-shadow: none;
}
// .col {
// padding: 2px;
// display: table-cell;
// flex-basis: 100%;
// flex: 1;
// }
// .cuts-btn {
// font-size: 11px;
// padding: 3px;
// width: 100%;
// box-shadow: none;
// }
}
}
}
}
I have all of the <Button> wrapped in <Col> because that should be what is filling the white space by increasing the size of the button.
Thanks for the help!
IE11 doesn't like working out the width of flex items. If you add flex-basis: calc( 100% / 24 ); to .col it works :) Obviously use any width you want, but what I've given replicates the 21 boxes on one line. But essentially flex-basis needs a defined width to work.
Or add an extra class to each element (such as col-1 ) This'll also achieve the same thing.