Align input with labels to button without label (vertically) - reactjs

I want to align input, which has two labels with a button that doesn't have any labels so that they are both on the same level.
Here's desired effect:
Here's what I got so far:
I've managed to get this to look how I want by adding label with empty space before the button, which is not ideal.
Here's the code:
<Form>
<Form.Group widths='four'>
<Form.Field>
<Form.Input type='number' label='Input'/>
<label>We can't find any matches.</label>
</Form.Field>
<Form.Field>
<Button primary>Search</Button>
</Form.Field>
</Form.Group>
Thanks for your help
EDIT: Here's the link to CodeSandbox: https://codesandbox.io/s/v6kkmyzyr0

I think that this is a styles issue and it depends of the design framework that you are using ( if you are using one).
Answering your question you could use flex to align the items horizontally
Here is the code : https://codesandbox.io/s/1oro0o6943
import React from "react";
import { render } from "react-dom";
import { Button, Form } from "semantic-ui-react";
const App = () => (
<Form>
<Form.Group widths="four" style={{ display:"flex", flexDirection:"row", alignItems:"center", }}>
<Form.Field>
<Form.Input type="number" label="Input" />
<label>We can't find any matches.</label>
</Form.Field>
<Form.Field>
<Button primary>Search</Button>
</Form.Field>
</Form.Group>
</Form>
);
render(<App />, document.getElementById("root"));
I've made it with inline styles but you could manage this in several ways!

Try using flex
<Form.Group widths='four'>
<div style="display: flex; flex-direction:row; height
auto; align-items:
center">
<Form.Field>
<Form.Input type='number' label='Input'/>
<label>We can't find any matches.</label>
</Form.Field>
<Form.Field>
<Button primary>Search</Button>
</Form.Field>
</div>
</Form.Group>

Related

Chakra UI icon not positioned inside Input

I'm trying to position an icon correctly in the middle of an input, where that input has size="xs". However, all my attempts have failed, and the icon keeps being positioned too low/down. I've also tried using IconButton instead of a regular icon but that didn't work either.
import { Input, InputGroup, InputLeftElement } from "#chakra-ui/react"
import { SearchIcon } from "#chakra-ui/icons"
// ...
<InputGroup>
<InputLeftElement
pointerEvents="none"
children={<SearchIcon color="gray.300"/>}
size="xs"
/>
<Input
variant="outline"
size="xs"
placeholder={``}
/>
</InputGroup>
What am I doing wrong?
Here's the codesandbox. Note that in this codesandbox, the icon is actually above the middle of Input (which is still wrong), instead of below as on my local machine.
https://codesandbox.io/s/optimistic-bartik-5ifsd?file=/src/App.tsx
You can solve the problem by adding className to chakra components and editing styles:
export default function App() {
return (
<InputGroup>
<InputLeftElement
className="InputLeft"
pointerEvents="none"
children={<SearchIcon className="SearchIcon" color="gray.300" />}
size="xs"
/>
<Input className="Input" variant="outline" size="xs" placeholder={``} />
</InputGroup>
);
}
And Here's the styles:
.InputLeft {
top: 3px !important;
left: 3px !important;
}
.Input {
padding-left: 24px !important;
}
If in your local, the icon is below the input. You can change the top to bottom in InputLeft class.
Here's the updated codesandbox :
This issue is solvable without CSS. You just have to add the size attribute to the InputGroup as well.
See the updated code sandbox.
<InputGroup size="xs">
<InputLeftElement
pointerEvents="none"
children={<SearchIcon color="gray.300" />}
size="xs"
/>
<Input variant="outline" size="xs" placeholder={``} />
</InputGroup>

How do I use the SpeedDial to upload a file?

(this seem to have been asked previously but I couldn't find any hint on if it was actually answered)
MUI has a good demo for creating upload buttons which boils down to:
<input accept="image/*" className={classes.input} id="icon-button-file" type="file" />
<label htmlFor="icon-button-file">
<IconButton color="primary" aria-label="upload picture" component="span">
<PhotoCamera />
</IconButton>
</label>
What I wonder is how to implement the same using the Speed Dial. Inherently the SpeedDialAction seems to materialize as a <button/>, but it's not possible to e.g. wrap the SpeedDialAction in a <label htmlFor /> as its parent will try to set some props on it and will fail.
So how do I initiate the file selection from within the Speed Dial or a FAB in general?
You can create a wrapper component that forwards props to SpeedDialAction.
function UploadSpeedDialAction(props) {
return (
<React.Fragment>
<input
accept="image/*"
style={{ display: "none" }}
id="icon-button-file"
type="file"
/>
<label htmlFor="icon-button-file">
<SpeedDialAction
icon={<CloudUploadIcon />}
tooltipTitle="upload"
component="span"
{...props}
></SpeedDialAction>
</label>
</React.Fragment>
);
}
https://codesandbox.io/s/material-demo-forked-h6s4l
(Note to future readers: For v5, time allowing, we hope to rationalise where props rather than context are used to control children, in order to solve exactly this kind of issue. So check whether this solution is still needed.)
It is - in my knowledge - not possible to add the htmlFor in any way. So what I would do is to add a hidden input type file and then add a ref to it. Then in the onclick of the SpeedDialAction button I would call a handler function that clicks on the input ref. Like this:
const inputRef = useRef();
const handleFileUploadClick = () => {
inputRef.current.click();
};
Then your SpeedDialAction:
<SpeedDialAction
onClick={handleFileUploadClick}
... the rest of your props
/>
And then finnaly your actual input:
<input
style={{ display: "none" }}
ref={inputRef}
accept="image/*"
id="contained-button-file"
multiple
type="file"
/>
Working demo: https://codesandbox.io/s/material-demo-forked-f9i6q?file=/demo.tsx:1691-1868

Conditionally remember radio button selection in React

I am creating a modal to filter for profiles, on react-bootstrap and redux.
I need to filter to remember it's previous selection every time the user reopen it, even if he returns from another page. It works fine with value based components, such as "range slider" or "text search" because I can grab the previous saved redux store and plug into the component's attribute, such as:
value={rangeValue}
But for radio buttons, I am not sure since the attribute itself, "checked", is its own value.
<Form.Check
inline
label="male"
name="male"
checked <-----------
onChange={(e) => onRadioChange(e)}
/>
I want it to show "checked" only if the user has previously done so. I already have the user choice (whether checked or not) saved in my store, but don't know how to plug it in conditionally.
The returned JSX below
import React, { useState } from "react";
import { Form, Button } from "react-bootstrap";
...
<Form>
<div className="form_content_wrap">
<Form.Group>
<Form.Label htmlFor="formControlRange">Age: {rangeValue}</Form.Label>
<Form.Control
type="range"
className="form-control-range"
id="formControlRange"
min="0"
max="100"
value={rangeValue}
onChange={(e) => setRangeValue(e.currentTarget.value)}
/>
</Form.Group>
<Form.Group>
<Form.Label htmlFor="formControlRange">Gender: </Form.Label>
<Form.Check
inline
label="female"
name="female"
onChange={(e) => onRadioChange(e)}
/>
<Form.Check
inline
label="male"
name="male"
checked <<<------- THIS IS WHERE I WANT TO CHANGE
onChange={(e) => onRadioChange(e)}
/>
</Form.Group>
<Form.Group>
<Form.Label>Keyword</Form.Label>
<Form.Control
type="text"
placeholder="search description"
value={descValue}
onChange={(e) => setDescValue(e.currentTarget.value)}
/>
</Form.Group>
<Button
variant="primary"
type="submit"
onClick={onFormSubmit}
style={{ marginRight: "10px" }}
>
Submit
</Button>
<Button variant="primary" type="submit" onClick={onFormClear}>
Clear
</Button>[enter image description here][1]
</div>
</Form>
Thanks
React appears to be smart enough automatically remove the attribute if you set it equal to a Javascript expression that is not truthy. You should be able to just pull this state from your store. See this question for more details.
<Form.Check checked={true} />
<Form.Check checked={false} />

How to extend React DatePicker pop-up once it's triggered to show?

There is an annoying problem when I try to implement DatePicker form input in my simple frontend project. I've a page that displays a user form based on this code:
import React, { Component } from 'react';
import AppNavbar from './AppNavbar'
import DatePicker from 'react-datepicker'
import './App.css'
import { Container, FormGroup, Form, Button, Input, Label } from 'reactstrap'
import {Link} from 'react-router-dom'
class CostLog extends Component {
state = { }
render() {
return (
<div>
<AppNavbar />
<h2 style={{display: 'flex', justifyContent: 'center', alignItems: 'center', height: '50px'}}>Cost overview</h2>
<Container>
<Form>
<FormGroup>
<Label for='title'>Title</Label>
<Input className='input-cust' type='text' name='title' id='title' onChange={this.inputHandler} />
</FormGroup>
<FormGroup>
<Label for='title'>Category</Label>
<Input type='text' name='category' id='category' onChange={this.inputHandler} />
</FormGroup>
<FormGroup>
<Label for='date'>Date of Payment</Label>
<div className='datepicker-cust'>
<DatePicker className='datepicker-cust' onChange={this.inputHandler} value={this.state.date} />
</div>
</FormGroup>
<FormGroup>
<Label for='Place of Receipt Issuance'>Place of Invoicing</Label>
<Input type='text' name='place' id='place' onChange={this.inputHandler} />
</FormGroup>
<FormGroup>
<Button color='info' type='submit'>Save</Button>{' '}
<Button color='secondary' tag={Link} to="/cat/total">Drop</Button>
</FormGroup>
</Form>
</Container>
</div>
);
}
}
export default CostLog;
Additively, case-related snippets inside of stylesheet file:
.datepicker-cust {
width: 500px;
}
.react-datepicker-wrapper, .react-datepicker__input-container {
display: block !important;
}
To be noted, I use div around DatePicker to make this field a bit broader. Whenever it's clicked, picker appears as a single column of days above the field, i.e. all days follow each other in vertical order, nothing like a normal calendar view I want to see. Using developer tool in Chrome, Mozilla, etc., I can suggest the problem takes its origin in zero width of Popper: it has a width equal to 0 and length 200.
This project I'm working on is just my first experience with React and its components. I found out what might be inconsistent here (supposing Popper has wrong size). This solution for a topic-related issue doesn't work in my case: still the same vertical column of numbers instead of two-dimensional calendar pop-up. What needs to be changed in properties to display that as expected?
I had the same problem until I imported the .css file.
import "react-datepicker/dist/react-datepicker.css";

Horizontal alignment of elements - Semantic-UI-react

Solution: Add "inline" to Form.Group. Codepen: https://codesandbox.io/s/88v6zl66q8
I'm setting up a selection form group in semantic UI in react. However the alignment is off horizontally, so the Radio selection items are floating above an input field (see attached picture).
How do I align them? I would prefer a Semantic-UI way of doing it, and not writing custom CSS (but I'm open to suggestions). Thanks!
https://i.imgur.com/IW1imch.png
When putting the elements in a Grid or Menu container, it doesn't solve the issue.
<Form.Group>
<Form.Field>
<Radio />
<Divider vertical hidden />
</Form.Field>
<Form.Field>
<Radio />
</Form.Field>
<Form.Field>
<Radio />
</Form.Field>
<Form.Field>
<Radio />
</Form.Field>
<Form.Field>
<Radio />
</Form.Field>
<Form.Field>
<Input/>
</Form.Field>
</Form.Group>
I think the easiest way would be to put them in a display: flex container, and set align-items: center on it, as explained here.
Not quite sure, whether I got what you mean. But to prevent the radio buttons floating above the input field, you could arrange them via Semantics grid system:
<Form>
<Grid>
<Grid.Column width={8} stretched verticalAlign="middle">
<Form.Group inline className="no-margin">
<Form.Field><Radio /></Form.Field>
<Form.Field><Radio /></Form.Field>
<Form.Field><Radio /></Form.Field>
<Form.Field><Radio /></Form.Field>
<Form.Field><Radio /></Form.Field>
</Form.Group>
</Grid.Column>
<Grid.Column width={8}>
<Form.Field>
<Input
label="Anden værdi"
name="n"
type='text'
labelPosition='right'
/>
</Form.Field>
</Grid.Column>
</Grid>
</Form>
So, you can achieve a vertical align with verticalAlign="middle".
The problem is, that per default Semantic` fields have a margin. We can overcome this only via adding a class and writing one argument additional css:
.no-margin {
margin: 0 !important;
}
(See codepen: https://codesandbox.io/s/m3y9zpw358)

Resources