semantic ui react reveal interact with hidden form - reactjs

Using Semantic ui React's Reveal with two different Cards. The visible one and then the hidden one. But the hidden one has a form and button that I need to interact with. Is there an easy way to make the form accessible? Or is the really only way to do so find the item with JS and then remove the attribute to interact with? Please someone give me some advice. Here is my current code for the Reveal.And yes I know code is sloppy right now. It's temporary.
<Reveal animated='fade' instant key={i}>
<Reveal.Content visible>
<Card
centered={true}
key={i}
raised={true}
style={{'backgroundColor':'blue', color:'white'}}
>
<Card.Header textAlign='center' as='h1'>
{Object.keys(each).toString()}
</Card.Header>
<Card.Header textAlign='center' as='h3'>
No peeking on other players wagers!
</Card.Header>
<Card.Header as='h1'></Card.Header>
<Card.Header as='h1'></Card.Header>
<Card.Header as='h2'></Card.Header>
</Card>
</Reveal.Content>
<Reveal.Content hidden>
<Card
centered={true}
key={i}
raised={true}
>
<Card.Header textAlign='center' as='h1'>
{Object.keys(each).toString()}
</Card.Header>
<Card.Header textAlign='center' as='h3'>
Please make your wager!
</Card.Header>
<Card.Content>
<Form
as='form'
>
<Form.Field>
<Label>Place your Wager</Label>
<Input icon='money' iconPosition='right' focus placeholder='Wager' />
</Form.Field>
<Button
type='submit'
size='large'
color='blue'
>
Submit
</Button>
</Form>
</Card.Content>
</Card>
</Reveal.Content>
</Reveal>

Technically your top content in your Reveal is covering the form below. Only the opacity is changing. It's still in the DOM with a higher z-index.
There are a number of ways you could solve this.
1) When the animation ends, set a display: none on the top "visible" Reveal. That means you'd have to listen to the animation end. And when the mouse leaves you would need to add display: block back so you can see the animation. Probably more work than you need.
2) Change the z-index to a lower value when the animation ends. Same issue as above.
3) Set pointer-events: none on the top "visible" reveal. This effectively makes the user's click events pass through the transparent Reveal and hit the form below instead. This is important to know, in case you intend to use the Reveal at some point to actually block the form. <Reveal.Content visible style={{pointerEvents: 'none'}}>

Related

add onHover to react grid gallery

Does anybody know how to add onhover effect to react grid gallery?
I have figured out that onhover event needs to be added to the parent element of Gallery.
However, dont know where to go from there.
I need image to increase in size a bit when u hover over it.
<Box sx={maingrid}>
<Box onMouseOver={handleHover}>
<Gallery
images={images}
margin={1}
maxRows ={{xs:4,lg:2, xl:2}}
rowHeight={300}
onClick={handleClick}
enableImageSelection={false}
/>
{!!currentImage && (
<Lightbox
mainSrc={currentImage.original}
imageTitle={currentImage.caption}
mainSrcoriginal={currentImage.src}
nextSrc={nextImage.original}
nextSrcoriginal={nextImage.src}
prevSrc={prevImage.original}
prevSrcoriginal={prevImage.src}
onCloseRequest={handleClose}
onMovePrevRequest={handleMovePrev}
onMoveNextRequest={handleMoveNext}
/>
)}
so what do i need pass in handleHover finc? thanks!

Next.js and React Bootstrap accessibility component to change font and font size

I am trying to create a component for accessibility and have the option to change settings such as dark mode, higher contrast, font size, etc.
I've made a component as a bootstrap modal where settings for accessibility can be changed. Dark mode and higher contrast are implemented and working.
The problem I am running into is changing font sizes. I want to be able to dynamically set the font size to a smaller or larger size. My idea was to add a class to the <body> tag since there are some articles out there showing how to set classes in the body tag dynamically in _document.js.
I cannot figure out a good way to implement this and might be looking at it the complete wrong way.
For a better view of what's done so far I have setup a CodeSandbox with the complete code:
https://codesandbox.io/s/nextjs-react-bootstrap-accessibility-exndhh
As of now the accessibility component looks like this:
import { useState, useEffect } from "react";
import { useTheme } from "next-themes";
import { Button, Modal, Form } from "react-bootstrap";
import { UniversalAccess } from "./Icons";
const Accessibility = () => {
// A11Y - Accessibility modal
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
// A11Y - Accessibility themes
const [mounted, setMounted] = useState(false);
const { theme, setTheme, resolvedTheme } = useTheme();
// When mounted on client, now we can show the UI
useEffect(() => setMounted(true), []);
if (!mounted) return null;
return (
<>
<Button
variant="warning"
className="px-4 py-2 ms-lg-3 d-flex align-items-center"
onClick={handleShow}
>
<UniversalAccess className="me-2" />
Accessibility
</Button>
<Modal show={show} onHide={handleClose} centered>
<Modal.Header closeButton>
<Modal.Title>Accessibility settings</Modal.Title>
</Modal.Header>
<Modal.Body>
<p className="h5">Colors</p>
<Form.Check
type="switch"
id="dark-mode"
label="Dark mode"
onChange={() => setTheme(theme === "dark" ? "light" : "dark")}
checked={resolvedTheme === "dark"}
/>
<Form.Check
type="switch"
id="contrast-mode"
label="Higher contrast"
onChange={() =>
setTheme(theme === "contrast" ? "light" : "contrast")
}
checked={resolvedTheme === "contrast"}
/>
<div className="my-4">
<p className="h5">Font size/type</p>
<div className="d-flex mb-1 align-items-end">
<div className="d-flex flex-column align-items-center">
<Button
className="rounded-pill d-flex align-items-center justify-content-center"
variant="outline-primary"
style={{ width: "30px", height: "30px" }}
>
<span style={{ fontSize: "0.7rem" }}>A</span>
</Button>
<p>Small</p>
</div>
<div className="d-flex flex-column align-items-center">
<Button
className="mx-3 rounded-pill d-flex align-items-center justify-content-center"
variant="outline-primary"
style={{ width: "40px", height: "40px" }}
// Should be active because default font size
active
>
<span style={{ fontSize: "1rem" }}>A</span>
</Button>
<p>Default</p>
</div>
<div className="d-flex flex-column align-items-center">
<Button
className="rounded-pill d-flex align-items-center justify-content-center"
variant="outline-primary"
style={{ width: "50px", height: "50px" }}
>
<span style={{ fontSize: "1.5rem" }}>A</span>
</Button>
<p>Large</p>
</div>
</div>
<Form.Check
type="switch"
id="dyslexia-mode"
label="Dyslexia font"
/>
</div>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
);
};
export default Accessibility;
Eventually I'd like to have the option to changes fonts dynamically as well any suggestions here are more tan welcome!
The goal here is not to become fully WCAG compliant but at least have some of it.
Perhaps there's one of those handy dandy react libraries out there and have not found it yet.
Typically, we (my company) leave that up to the user agent to determine the font and font size. For example, in Firefox, under "Fonts" you can tell the browser to override a webpage's font and font size; also, under "Zoom" you change the page zoom. In Chrome, under "Appearance," you can do the same.
This appears to be the recommended approach by WCAG2.1 and by me (and you'll see why below).
The scaling of content is primarily a user agent responsibility. User agents that satisfy UAAG 1.0 Checkpoint 4.1 allow users to configure text scale. The author's responsibility is to create Web content that does not prevent the user agent from scaling the content effectively.
When designing for accessibility, the best advice I can give would be to determine what WCAG2.1 considers sufficient for resizing text.
That said, the problems you're going to run into because of nextjs and react-bootstrap:
Persistence -- using context inside a modal gets super hacky (you'd need to have the context always in the DOM, which means the modal would need to reside under div#__next, which isn't??? currently possible with react-bootstrap because it appends modals to the body and outside of div#__next container) and
local storage is client-side only, so you'll get a massive CLS
when the page is SSR'd.
Support -- according to WCAG, you need to support up to a 200% font size. Therefore, you'll probably want to have some sort of stepping: 100%, 125%, 150%, 175%, 200%.
Layout -- by supporting variable font sizing, you'll also need to support variable layouts. Otherwise, the text can take up more space than visually expected: breaking containers, breaking form inputs, elongating buttons vertically, and wrapping some sort of text that makes it harder to read. This is expected when changing the font in a user-agent, but since you're supporting font resizing, you'll definitely want to also support different layouts (as mentioned in the sufficient link above).
Screen readers -- currently your font size buttons aren't communicating their intent; they're being read as "Push button" without any context. You'll need to use semantic markup or aria attributes for it to be picked up a screen reader. If you want to dive into it, I know for sure that Mac OS and most popular Linux distros have built in screen readers in their accessibility system settings -- no idea about Windows.
Is it possible to accomplish the above? Yes, but maybe not (as easy/at all) with the 3rd party libraries you're using.
Before solving the above, I'd ask myself: At what cost (to you, a company or a client) is this going to take to solve these problems, and more importantly, what value does this feature bring that can't be accomplished natively?

How to show/hide Tab conditionally -React js

I need a condition for the below code, when we go through the address id, it will show only the upgrade page tab and will go through bricks, it will show only the new purchase page tab only.
Now it is showing both tabs. I need one tab for conditonally. Please help with this.
If I understand your question correctly, you can use the selectActive tab to hide / display the tab of your choice like this:
<Row className="mt-3">
<Col>
<Tabs onSelect={selectTab} defaultActiveKey={selectActive()} id="uncontrolled-tab-example" style={{ backgroundColor: 'rgb(237 245 240 / 38%)' }}>
{selectActive() === "newPurchase" && (
<Tab eventKey="newPurchase" title="New Webshop">
<NewPurchase/>
</Tab>
)}
{selectActive() === "upgrade" && (
<Tab eventKey="upgrade" title="Existing Webshop">
<Upgrade/>
</Tab>
)}
</Tabs>
</Col>
</Row>
It will show / hide the tab depending upon the value returned from the function. By the way, your question needs more clarity

using Link from react-router-dom with button

I am using react-bootstrap Cards on my project. I have great view with that. I have horizontal search button on it. I would like to use this button for routing.
I set my settings on my app.js class. Actually, I can change route with <Link> but my search button looks bad with it. I would like to use Search button while keeping visual design.
Sorry for my explanation, It's hard to explain without any visual support. if it is not clear please leave comment and I would try to clarify with onether way.
Here is my codes;
<Card bg="dark" text="white" style={{ width: "18rem" }}>
<Card.Header>SWITCH</Card.Header>
<Card.Body>
<Card.Title>Dark Card Title</Card.Title>
<Card.Text>
Some quick example text to build on the card title and make up
the bulk of the card's content.
</Card.Text>
</Card.Body>
<Button variant="secondary">SEARCH</Button>
</Card>
I can do routing with wit this code;
<Card bg="dark" text="white" style={{ width: "18rem" }}>
<Card.Header>SWITCH</Card.Header>
<Card.Body>
<Card.Title>Dark Card Title</Card.Title>
<Card.Text>
Some quick example text to build on the card title and make up
the bulk of the card's content.
</Card.Text>
</Card.Body>
<Link to={"/route which I defined in app.js"}>
<Button variant="secondary">SEARCH</Button></Link>
</Card>
But this time, search button's size decrease. Are there any way to stretch it? Or should I change usage of <Link> ?
You can use a package called react-router-bootstrap from npm and use it. It's very simple and for your use case find the below snippet.
<Link to={"/route which I defined in app.js"}><Button]>Foo</Button></Link>
becomes
import { LinkContainer } from 'react-router-bootstrap'
<LinkContainer to={"/route which I defined in app.js"}>
<Button>Foo</Button>
</LinkContainer>
find more on react-router-bootstrap
You probably will need to do some custom css styling still. You can open up your elements browser by clicking inspect in chrome and find the class of the link, then you can overwrite that class to match your styling needs.
Also try wrapping the link with the button
<Button variant="secondary"><Link>SEARCH</Link></Button>
NOTE: Even though it's not recommended and you should normally avoid it, you might need to use !important in your css when overwriting bootstrap.
you can try,
<Button as={Link} to="/your_destination">Foo</Button>

Typography in React Material-UI

I've this textbox:
<Typography component="p" className={classes.text}>
{this.props.post.text}
</Typography>
I'd like to be able to include paragraphs but all text entered into it gets printed on one line.
The documentation suggests that paragraph is defaulted to false so I must set it to `true.
I've tried the following:
<Typography component="p" className={classes.text} paragraph="true">
I also tried:
<Typography component="p" className={classes.text} paragraph={true}>
Neither work so all my text still gets printed to one line.
How do I get the paragraphs to show?
Additional info:
As I now understand, the paragraph={true} attribute in Typography just adds a bottom-margin to the whole text. I.E. my one block of text is a paragraph. If I want another paragraph I would have to add another Typography. Something like:
<Typography component="p" className={classes.text} paragraph={true}>
{this.props.post.text}
</Typography>
<Typography component="p" className={classes.text} paragraph={true}>
{this.props.post.text2}
</Typography>
This is not exactly what I want. Perhaps what I should be aiming for is to have the return characters in my input text recognised. Is this correct and if so, how is it done?
I tried this:
<pre>
<Typography component="p" className={classes.text}>
{this.props.post.text}
</Typography>
</pre>
The tag preservers the whitespace and line breaks inside the tags as is.
This is not suitable though. If I have long line the text does not wrap at the Card width. Instead anything beyond the width of the card becomes truncated. Clearly I want it all. I want my text to wrap in the card and also for it to support new lines and paragraphs. How is this done?
A better way is to use power of css:
white-space: pre-line
"New line" character will be respected if you use this css property.
Edit: Help from Ionut-Alexandru Baltariu
<Typography id="modal-description" sx={{ whiteSpace: 'pre-line'}}>
For new paragraphs
<Typography>
{this.props.text.split("\n").map((i, key) => {
return <p key={key}>{i}</p>;
})}
</Typography>
For just new lines
<Typography>
{this.props.text.split("\n").map((i, key) => {
return <div key={key}>{i}</div>;
})}
</Typography>
I tried your answer and it worked perfectly as needed. However, the console returns a minor error
Warning: validateDOMNesting(...): <p> cannot appear as a descendant
of <p>.
I improved on your answer slightly by replacing the <p> tags in your .map() with <Typography> and wrapping it all in a <div> instead, like so:
<div className={classes.text}>
{this.props.post.text.split('\n').map((i, key) => {
return <Typography key={key} paragraph variant="body1">{i}</Typography>;
})}
</div>
(you can replace body1 with whichever variant you want!)
This seems to get rid of the warning for me and I hope works as you intended.
I've come up with this:
<Typography component="p" className={classes.text}>
{this.props.post.text.split("\n").map((i, key) => {
return <p key={key}>{i}</p>;
})}
</Typography>
If there is a better way to do this I'd be keen to hear it.
This really is a strange behavior. From what I can tell, you are doing everything correctly. p is by itself displayed as block element so it should be by default displayed the way you want it to be. But, it could be that you are overriding that in your .text css class. Try to see if there is you problem. If not, you can always use variant property variant="headline" in order to put them on new lines.
If I get this right, you could simply leverage the power of HTML and add <br />-elements, to insert line-breaks.
This worked for me:
<Typography component="pre">
{this.props.post.text}
</Typography>
Starting in Material UI V5 you can now access many CSS utilities as props. For whitespace, you can now do:
<Typography whiteSpace="pre-line">{this.props.post.text}</Typography>

Resources