Use Bootstrap "prepend" with react-select - reactjs

I'm trying to use the Bootstrap input-group-prepend with react-select, however react-selects' styling doesn't seem to be the current bootstrap/reactstrap and so doesn't want to work together.
The select box doesn't merge with the prepend element (radius 4px on all corners instead of just right corners), also the box shadow on the element is totally different to what bootstrap 4 uses, this creates an annoying consistency issue.
This gives the desired look and feel, and stays the same when using .map for the options.
<InputGroup className="mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText><FaBriefcaseMedical /></InputGroupText>
</InputGroupAddon>
<Input type="select" name="select" id="ConsultantSelect">
<option value="" value disabled selected>Select Consultant</option>
<option>Roland Deschain</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Input>
</InputGroup>
This however is using react-select doesn't display as expected/desired
<InputGroup className="mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText><FaHSquare /></InputGroupText>
</InputGroupAddon>
<Select
options={this.state.hospitals}
name={this.state.hospitals}
/>
</div>
Iconography is important for what I'm doing due to the target audience.
EDIT:
a janky work around is to give the react-select className="form-control" and then then style it to match Bootstrap4.
<InputGroup className="mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText><FaHSquare /></InputGroupText>
</InputGroupAddon>
<Select className="form-control"
options={this.state.hospitals}
name={this.state.hospitals}
/>
</InputGroup>
.css-2b097c-container {
padding: 0px;
}
.css-yk16xz-control {
background-color: #ffffff00 !important;
border-style: none !important;
}
.css-1pahdxg-control {
border-color: #80bdff !important;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25) !important;
border-top-left-radius: 0 !important;
border-bottom-left-radius: 0 !important;
}
But this is clearly not a ideal solution.
The CCS changes result in the below, which now has the drop down appearing the same as a normal select input, and also matches the other inputs such as the text inputs.

What worked for me was to wrap the Select in a div with the class "form-control". It also needs a zero padding.
<div className="react-select form-control p-0">
<Select />
</div>
The first div inside Select also needs a -1px margin.
.react-select > div {
margin: -1px;
}

I have the same use case as you. Only I've been wrapping Select in a div with a % width style defined.
However, this has to be set for a screen size. It will cause the right side to be misaligned if the % is too small, or will create a new line if the % is too large.
<InputGroup className='mt-1'>
<InputGroupAddon addonType="prepend">
<InputGroupText>Select</InputGroupText>
</InputGroupAddon>
<div style={{width: '80%'}}>
<Select isMulti name='subjects'
options={optionsArray}
placeholder="Click or type"
/>
</div>
</InputGroup>

Related

Why does Cypress not recognise the testid of a react-datepicker element?

Target
To make Cypress recognise and manipulate a DatePicker element.
Problem
I cannot make Cypress recognise the data-testid of a DatePicker element, and so have no way of testing it E2E.
Error
Timed out retrying: Expected to find element: [data-testid="edit_dob"], but never found it.
Attempts
I have tried placing the DatePicker element inside input and div elements to target instead, but they fail as expected for other reasons.
I have also looked through the docs for both DatePicker and Cypress for mention of the other, and for similar questions here.
Code
The code below works as expected, it's just Cypress that seems to be incompatible with the DatePicker input.
function displayEditDetails() {
let listOfForms = [];
for (const detail in details) {
listOfForms.push(
<FormGroup controlId={detail} key={`key_edit_${detail}`}>
<FormLabel>{detail.charAt(0).toUpperCase() + detail.slice(1).replace('_', ' ')}</FormLabel>
<FormControl
data-testid={`edit_${detail}`}
type={detail}
value={details[detail] || ''}
onChange={handleDetailsChange}
/>
</FormGroup>
)
}
listOfForms.push(
<DatePicker
data-testid={'edit_dob'}
selected={dob}
onChange={setDob}
maxDate={new Date()}
/>
);
return(
listOfForms
)
}
Test
it('Displays the edit fields', () => {
cy.get('[data-testid="accountButton"]')
.click();
cy.get('[data-testid="editUserDetailsButton"]')
.click();
cy.get('[data-testid="user_email"]')
.should('not.be.visible');
cy.get('[data-testid="edit_full_name"]')
.should('be.visible');
cy.get('[data-testid="edit_dob"]')
.should('be.visible');
cy.get('[data-testid="edit_email"]')
.should('be.visible')
.should('have.value', 'test#editdetails.com');
})
Once I can target it, I plan to test clearing the current input and typing a new date in. Any help targeting the picker and warnings of further potential pitfalls are appreciated.
Edit: Here's the generated HTML of the form.
<form>
<div class="form-group">
<label class="form-label" for="email">Email</label>
<input data-testid="edit_email" type="email" id="email" class="form-control" value="admin#example.com" style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVQ4EaVTO26DQBD1ohQWaS2lg9JybZ+AK7hNwx2oIoVf4UPQ0Lj1FdKktevIpel8AKNUkDcWMxpgSaIEaTVv3sx7uztiTdu2s/98DywOw3Dued4Who/M2aIx5lZV1aEsy0+qiwHELyi+Ytl0PQ69SxAxkWIA4RMRTdNsKE59juMcuZd6xIAFeZ6fGCdJ8kY4y7KAuTRNGd7jyEBXsdOPE3a0QGPsniOnnYMO67LgSQN9T41F2QGrQRRFCwyzoIF2qyBuKKbcOgPXdVeY9rMWgNsjf9ccYesJhk3f5dYT1HX9gR0LLQR30TnjkUEcx2uIuS4RnI+aj6sJR0AM8AaumPaM/rRehyWhXqbFAA9kh3/8/NvHxAYGAsZ/il8IalkCLBfNVAAAAABJRU5ErkJggg=="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;">
</div>
<div class="form-group">
<label class="form-label" for="full_name">Full name</label>
<input data-testid="edit_full_name" type="full_name" id="full_name" class="form-control" value="Jareth">
</div>
<div class="form-group">
<label class="form-label" for="address">Address</label>
<input data-testid="edit_address" type="address" id="address" class="form-control" value="">
</div>
<div class="form-group">
<label class="form-label" for="postcode">Postcode</label>
<input data-testid="edit_postcode" type="postcode" id="postcode" class="form-control" value="">
</div>
<div data-testid="edit_dob">
<div class="react-datepicker-wrapper">
<div class="react-datepicker__input-container">
<input type="text" class="" value="04/03/1999">
</div>
</div>
</div>
<button data-testid="confirmChangesButton" type="submit" class="LoaderButton btn btn-primary btn-block">Confirm Changes</button></form>
The problem is visible when looking at the HTML generated by running the app.
DatePicker HTML
<div data-testid="edit_dob">
<div class="react-datepicker-wrapper">
<div class="react-datepicker__input-container">
<input type="text" class="" value="04/03/1999">
</div>
</div>
</div>
The DatePicker is rendered as an input element inside a few divs, and the test id doesn't target the input.
Solution
The Selector Playground API for Cypress suggests cy.get('.react-datepicker__input-container > input'), the class of the parent div of the input. With this I can target the DatePicker, clear it, and type new input.
Notes For Next Time
Examine the HTML
Read the Docs more thoroughly
Reference the concepts used in the cy.pickDateRange command in the Cypress Real World App. It is a payment application to demonstrate real-world usage of Cypress testing methods, patterns, and workflows.
In the code for the command, you will find it is necessary to examine the HTML produced and traverse it appropriately for your needs.

Embed Lightning-input with lightning-icon in LWC

Can someone help with sample of embedding the lightning-icon inside a lightning-input in LWC
<lightning-input type="search" name="To Address" label="To"
class="slds-input-has-icon_right slds-m-bottom_small">
<lightning-icon icon-name=action:email>
</lightning-icon>
</lightning-input>
I have also tried the below Approach which doesn't work
<div class="slds-form-element">
<label class="slds-form-element__label" for="text-input-id-1">Input Label</label>
<div class="slds-form-element__control slds-input-has-icon slds-input-has-icon_right">
<lightning-icon icon-name="utility:adduser" size="medium">
</lightning-icon>
<input type="text" id="text-input-id-1" class="slds-input" />
</div>
Here is the solution!!
<lightning-button-icon class="btnIconOverlay" icon-name="utility:adduser">
</lightning-button-icon>
<lightning-input type="search" name="To Address" value={toAddress}>
</lightning-input>
Add the below CSS to the lightning-button-icon, which assist in overlaying the icon.
.btnIconOverlay {
position: absolute;
z-index: 1;
margin: 0.5% 0 0 92%;
}

React | CSS-Modules | Materialize-CSS: .browser-default not being applied

I am using Materialize-CSS in my React app with CSS-Modules.
I would like to use the default styling for input fields but when I try to apply the "browser-default" as indicated by the documentation linked below, the input fields still do not revert back to browser default styles.
https://materializecss.com/helpers.html#browser-default
import mStyles from 'materialize-css/dist/css/materialize.min.css';
<Field
label="EMAIL"
name="email"
inputStyle={`${styles.input} ${mStyles['browser-default']}`}
/>
The only solution I've found that comes close is to overwrite all the styles with !important. Obviously, this is inconvenient and hacky.
.input:focus {
border-bottom: none !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
}
Any suggestions for a workaround or what I could be doing wrong?
Just give classname: browser-default to <label> and <input> tag and it'll become just like a default text-field.
CodeSandbox - Input Field Demo {.browser-default}
<label className="browser-default">First Name</label>
<input
placeholder="Enter name"
type="text"
className="browser-default"
/>

ng-options in angular placeholder [duplicate]

This question already has answers here:
<select> placeholder with angular/bootstrap not working
(2 answers)
Closed 7 years ago.
I have a select box, Pretty basic, shown below
<div ng-if="field.field_type == 'select'">
<p><strong>{{field.field_name}}:</strong></p>
<div class="form_field"><label class="fontawesome-pencil" for="login_Custom"></label>
<div class="input-group col-xs-8">
<style media="screen">
select:not([multiple]) {
-webkit-appearance: none;
-moz-appearance: none;
background-position: right 50%;
background-repeat: no-repeat;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDZFNDEwNjlGNzFEMTFFMkJEQ0VDRTM1N0RCMzMyMkIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDZFNDEwNkFGNzFEMTFFMkJEQ0VDRTM1N0RCMzMyMkIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0NkU0MTA2N0Y3MUQxMUUyQkRDRUNFMzU3REIzMzIyQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0NkU0MTA2OEY3MUQxMUUyQkRDRUNFMzU3REIzMzIyQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuGsgwQAAAA5SURBVHjaYvz//z8DOYCJgUxAf42MQIzTk0D/M+KzkRGPoQSdykiKJrBGpOhgJFYTWNEIiEeAAAMAzNENEOH+do8AAAAASUVORK5CYII=);
padding: .5em;
padding-right: 1.5em;
}
</style>
<select class="selectpicker form-control" default-option="Test" name="cusdropdown" ng-model="testInfo" ng-options="i.val as (i.nam) for i in field.options" style="width:450px"></select> <span class="input-group-addon buttonlike" ng-click="removeRegistrationfield($index)"><i class="fa fa-trash"></i></span></div>
</div>
</div>
I'm wanting the field.field_name as the placeholder, I know how to do this in html, Which is like this
<select>
<option value="" disabled selected hidden>Please Choose</option>
<option value="0">Open when powered (most valves do this)</option>
<option value="1">Closed when powered, auto-opens when power is cut</option>
</select>
However how can i do this inside angular?
Thanks
You can use ng-options and add yourself a placeholder at the same time.
Duplicate : <select> placeholder with angular/bootstrap not working

IE7 float (not div's)

I wanted to make simple form, without awesome div's and CSS - it structure is like:
<form id="cform" action="/" method="post">
<fieldset>
<label class="first" for="name">Nazwa firmy: </label><input id="name" name="name" type="text" />
<label class="first" for="email">Email: </label><input id="email" name="email" type="text" />
</fieldset>
</form>
CSS
#cform input, #cform textarea, #cform label, #cform select
{
float: left;
}
label.first, #cform input[type="submit"]
{
margin-bottom: 10px;
width: 150px;
float: left;
clear: both;
}
#cform textarea
{
width: 400px;
height: 250px;
margin-bottom: 10px;
}
In FF, IE8, Chrome and Opera it looks good. But in IE7 inputs are looking, like they don't have float at all. How to fix it? (version without adding divs please)
Aww, forgot link
http://site.amm.siedlce.pl/front/page/get/79/
IE7 doesn't support the attribute selector, input[type="submit"].
Reference them by class.

Resources