Chakra UI icon not positioned inside Input - reactjs

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>

Related

Setting "max" on an Input with type "number" in Chakra-UI

While building a user interface with a few inputs, I decided to migrate the base input components to form a single component I can use, while that's not really the problem. Here's the code for it. For easy and memorable use for Inputs.
import {
FormControl,
FormErrorMessage,
FormHelperText,
FormLabel,
Input,
} from "#chakra-ui/react";
const DefaultInput = ({
isInvalid,
label,
helperText,
errorMessage,
...otherProps
}) => {
return (
<FormControl isInvalid={isInvalid}>
{label && <FormLabel>{label}</FormLabel>}
<Input
variant="outline"
padding="25px 10px"
margin="10px 0px"
border={"0px"}
{...(isInvalid && { border: "0px" })}
{...otherProps}
/>
{!isInvalid ? (
<FormHelperText>{helperText}</FormHelperText>
) : (
<FormErrorMessage>{errorMessage}</FormErrorMessage>
)}
</FormControl>
);
};
export default DefaultInput;
Used it like this but it doesn't seem to take notice of the "max" property.
<DefaultInput
value={custom.credits}
isInvalid={creditsError}
helperText={"Minimum of 50 Credits."}
errorMessage={"Please enter a valid number above 50."}
maxW={isNotSmallerScreen ? "50%" : "70%"}
fontSize={!isNotSmallerScreen ? "12px" : "16px"}
onChange={handleCustomCredit}
type="number"
placeholder="Enter Credits"
name="credits"
max="5000"
/>
I've also tried manually declaring the "max" and "type" within the component I created but still nothing.
.....
<Input
variant="outline"
padding="25px 10px"
margin="10px 0px"
border={"0px"}
max="5000"
type="number"
{...(isInvalid && { border: "0px" })}
{...otherProps}
/>
.....
This is actually a browser quirk and not related to Chakra. max HTML5 attribute won't actually restrict you from typing larger numbers until you submit the containing form. If you want to limit it on the fly you have to build out your own function.
Unless you aren't seeing anything on submit either? See this example of what you should see https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_max_min.

Textfield's label gets clipped when inside a Dialog

When using a Textfield as the first child of DialogContent:
export default function App() {
return (
<Dialog open={true}>
<DialogTitle>Hey</DialogTitle>
<DialogContent>
<TextField
fullWidth
id='name'
label={'Foo'}
name='name'
required
type='text'
value={'Bar'}
/>
</DialogContent>
</Dialog>
);
}
its label (when using `variant="outlined") gets clipped. See codebox sample. Any way to fix this problem? e.g. by customizing the theme?
You can easily fix that issue by adding some margin to the TextField like the following.
sx={{ marginTop: 2 }}
Or you could wrap the TextField using Box inside the DialogContent like the following.
<Box p={1}>
<TextField
...
/>
</Box>

Is the z-index incorrect for these radio toggles behind the Semantic-UI-React Loading component?

I'm working on a form that has Semantic-UI Radio toggles, and the loader and the toggle's appear to be loading in the wrong z-index.
I checked the css and the toggle contains the following
.ui.toggle.checkbox label:after {
z-index: 2;
}
while the loader is
.ui.dimmer {
z-index: 1000;
}
which seems like the appropriate behaviour. I want the toggles to be behind the loader to present the best user experience. Can anyone tell me if the current behaviour is by design or not? Trying to determine if this is a bug to be reported or a feature to be requested or if there's a problem with my implementation.
My code (edited for brevity)
import { Form, Dropdown, DropdownItemProps, Dimmer, Loader, Button, Icon, Segment } from "semantic-ui-react";
return (
<Fragment>
<div style={{ display: "flex", flexDirection: "column" }}>
<div className="ui segments">
<PageHeader
text="Some text"
subText="Some subtext"
pageIcon="cogs icon"
/>
</div>
<Dimmer.Dimmable dimmed={loading}>
<Dimmer simple active={loading}>
<Loader>Loading</Loader>{" "}
</Dimmer>
<Form onSubmit={() => save()}>
<Form.Checkbox
label="Label 1"
checked={display}
onChange={(e, { checked }) => setDisplay(!!checked)}
toggle
/>
<Form.Input
label="Label 2"
placeholder="Placeholder"
value={data}
onChange={(e, { value }) => setData(value)}
/>
</Form.Group>
</Form>
</Dimmer.Dimmable>
</div>
</Fragment>
);
The comment helped me out. The problem was resolved using https://coder-coder.com/z-index-isnt-working/#alternative-solution-remove-positioning-from-the-content-so-it-wont-limit-the-modals-z-index from the suggestion.
I used a sticky position for the form element. Not necessarily the best solution but it sufficed for this purpose.

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";

Align input with labels to button without label (vertically)

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>

Resources