It's now clear to me that mixins and inheritance are generally considered bad and composition is the way to go, this from:
https://medium.com/#dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750
https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html
Now, what to do when you find two components that specialize in different things and you want a component that is the result of both behaviors mixed? For instance, I want a textarea that both grows automatically when text goes beyond initial rows, and allow mentions inside (aka. mix react-mentions with react-textarea-autosize)
How am I supposed to compose both in a way that works?
Am I supposed to code a brand new component copying/merging the inner code from both components?
What's the ReactJs way to compose in such scenarios?
I came across the same issue. With react-mention you don't have to use the react-text-autosize as you can achieve the same behavior with css which can auto grow the textarea generated. Consider following example
<MentionsInput
value={content}
placeholder="Add a comment"
onChange={this.onChange}
className="mentionWrapper">
<Mention
trigger="#"
data={users}
className="mentionedFriend"
displayTransform={(id, display) => `#${display}`}
/>
</MentionsInput>
For this i've used the following styles
.mentionWrapper {
width: 100%;
background: transparent;
font-size: 0.9rem;
color: #a9b5c4;
}
.mentionWrapper .mentionWrapper__control {
border-radius: 25px;
border: 1px solid #3a546f;
min-height: 45px;
}
.mentionWrapper .mentionWrapper__control .mentionWrapper__highlighter {
padding: 0.7rem 1rem;
}
.mentionWrapper .mentionWrapper__control .mentionWrapper__input {
padding: 0.7rem 1rem;
outline: 0;
border: 0;
resize: none;
outline: none;
font-size: 0.9rem;
color: #7288a3;
border-color: #3a546f;
overflow: hidden;
}
.mentionWrapper .mentionWrapper__control .mentionWrapper__input::placeholder {
color: #7288a3;
}
.mentionWrapper__suggestions {
background-color: rgba(0, 0, 0, 0.6) !important;
padding: 10px;
-webkit-box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
border-radius: 0.8rem;
}
.mentionWrapper__suggestions .mentionWrapper__suggestions__list {
font-size: 14px;
}
.mentionWrapper
.mentionWrapper__suggestions
.mentionWrapper__suggestions__item--focused {
color: #ffffff;
border-bottom: 1px solid #3a546f;
font-weight: 600;
}
.mentionedFriend {
color: #7288a3;
text-decoration: underline;
}
Key point here is that i've applied a min-height of 45px to "control" div which is append by react-mention package. By doing so you will get the attached result.
Related
The working on a project I can't understand why the heights of my components are fixed around 200px to 500px randomly.
I have tried adding height to the root id, but it doesn't affect the div they remain the same.
I'm adding a screenshot for better understanding:
What will be the best way to fix this, as my goal is to make this project dynamic. When I add more fields or elements, then this will be the big problem, causing other elements to lap over - like my footer is overlapping the elements, if I want to add more as in the image:
Global CSS Variables:
:root{
--clr-white: #fff;
--clr-black: #111;
--clr-grey-light: #f7f7f7;
--clr-grey-lighter: #ebebeb;
--clr-grey-lightest: #d8d8d8;
--clr-grey-dark: #999;
--clr-grey-darker: #777;
--clr-grey-darkest: #333;
--transition: all 0.3s linear;
--spacing: 0.25rem;
--radius: 2rem;
--sm-radius: 1rem;
--light-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
--light-shadow-white: 0 0 10px rgba(200, 200, 200, 0.1);
--dark-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
--dark-shadow-white: 0 0 10px rgba(200, 200, 200, 0.3);
--max-width: 1170px;
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
font-size: 16px;
background: var(--clr-black);
font-family: futuramedium;
}
.container{
max-width: var(--max-width);
margin: 0 auto;
padding: 0 10vw;
}
So Im using Bootstrap 3, JQuery and Jquery-UIs autocomplete. So on the my project, the result looks like this,
But according to the documentation page, it is supposed to look like this
with the clickable items on mouse over and everything. My search box HTML is as follows:
<form role="search" class="navbar-form navbar-left">
<div class="form-group">
<input id="titles" type="text" placeholder="Search" class="form-control">
</div>
<button type="submit" class="btn btn-default">GO</button>
</form>
The documentation page for jquery-ui autocomplete widget is here
Any pointers? Thanks in advance. PS:The photos were taken by a potato :-)
#dmlittle gave me the idea
You need to also style the autocomplete widget the Boostrap way
.ui-autocomplete {
position: absolute;
z-index: 1000;
cursor: default;
padding: 0;
margin-top: 2px;
list-style: none;
background-color: #ffffff;
border: 1px solid #ccc
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
.ui-autocomplete > li {
padding: 3px 20px;
}
.ui-autocomplete > li.ui-state-focus {
background-color: #DDD;
}
.ui-helper-hidden-accessible {
display: none;
}
I want slide number on each navigation bar bullet points
HTML code
<div id="slideshow">
<div class="container">
<div class="flexslider showOnMouseover ">
<ul class="slides">
<li> <img src="sliders/images/1.png" alt="" /> <div class="flex-caption"><img src="sliders/images/1-1.png" alt=""></div></li>
<li> <img src="sliders/images/2.png" alt="" /> <div class="flex-caption"><img src="sliders/images/1-2.png" alt=""></div></li>
</ul>
</div>
you can do that by removing a class name
use the below code to do it as soon as the slider starts.
$('.flexslider').flexslider({
start : function(){
$('.flex-control-paging').removeClass('flex-control-paging');
}
});
NOTE: You may need to change some more css to make it look pretty
Anyone still looking for the solution to this as I was, it can be solved simply by modifying the style sheet 'flexslider.css'.
The script already gives each nav link a number, but hides the number from view using a text-indent of -9999px. To get the numbers back, modify the class '.flex-control-paging li a'. As an example, here's the original:
.flex-control-paging li a {
width: 11px;
height: 11px;
display: block;
background: #666;
background: rgba(0, 0, 0, 0.5);
cursor: pointer;
text-indent: -9999px;
-webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
-moz-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
-o-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px;
}
Modify it to:
.flex-control-paging li a {
width: 20px;
height: 20px;
font-size: 20px;
display: block;
background: #ddd;
cursor: pointer;
}
And...
.flex-control-paging li a:hover {
background: #333;
color:#eee;
}
.flex-control-paging li a.flex-active {
background: #333;
color:#FFF;
cursor: default;
}
Should give you a good starting point to add your own style to.
I made a form control which uses as its container (see the Yes/No toggler below)
Here's the code for that:
<span class="toggle">
<i>Yes</i>
<i>No</i>
<input type="hidden" name="toggle-value" value="0">
</span>
My CSS isn't relevant to the question, but it's included for comprehension of my control:
.toggle { width:auto; height: 20px; display: inline-block; position: relative; cursor: pointer; vertical-align: middle; padding: 0; margin-right: 27px; color: white !important;}
.toggle i { display: block; padding: 0 12px; width: 100%; height: 100%; -webkit-border-radius: 12px; -moz-border-radius: 12px; border-radius: 12px; text-align: center; font: 11px/20px Arial !important; text-transform: uppercase; }
.toggle i:first-child { -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5) inset; box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5) inset; background-color: #73B9FF; }
.toggle i:last-child { -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5) inset; box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5) inset; background-color: #cc0000; position: relative; top: -20px; z-index: -1; }
.toggle.on i:first-child { z-index: 1; } /* they overlap but on click they switch who gets to be on top. */
.toggle.on i:last-child { z-index: -1; }
.toggle.off i:first-child { z-index: -1; }
.toggle.off i:last-child { z-index: 1; }
.toggle.off i:last-child:before { content: " "; display:block; position:absolute; left:1px; top:1px; text-indent: -9999px; width: 18px; height: 18px; -webkit-border-radius: 11px; -moz-border-radius: 11px; border-radius: 11px; z-index: 1; background-color: #fff; } /* circle */
.toggle.on i:first-child:after { content: " "; display:block; position:absolute; right:-23px; top:1px; text-indent: -9999px; width: 18px; height: 18px; -webkit-border-radius: 11px; -moz-border-radius: 11px; border-radius: 11px; z-index: 1; background-color: #fff; } /* circle */
and the JS that makes it all work:
.on('click', '.toggle', function(){
var input = $(this).next('input');
if(input.val() == 1) {
$(this).removeClass('on').addClass('off');
input.val(0).change();
} else {
$(this).removeClass('off').addClass('on');
input.val(1).change();
}
}
The problem is that I'm using this all over my application for data-entry. Have you ever wanted to NOT use the mouse when you're entering a lot of data? Yeah, me too. So you hit TAB and a toggle like this should respond to the spacebar. But instead, since it's just a element, it is skipped altogether.
I'm hoping someone can help me solve the question of "how the heck do I make this a tab stop AND be in the correct order"?
==============
EDIT: HERE IS MY UPDATED JQUERY CODE CONTAINING THE SOLUTION:
$('.toggle').click(function(){
var input = $(this).next('input');
if(input.val() == 1) {
$(this).removeClass('on').addClass('off');
input.val(0).change();
} else {
$(this).removeClass('off').addClass('on');
input.val(1).change();
}
}).focus(function() {
$(this).bind('keydown', 'space', function(e){
$(this).trigger('click')
e.preventDefault();
});
}).blur(function() {
$(this).unbind('keydown');
}).attr('tabIndex', 0);
Try setting your tabindex to 0, on the non-anchor elements you would like to make "tabbable". For example tabindex="0". This way, you won't mess with the tabbing order, or have to throw tabindexs all over the place.
Look into the html attribute tabindex. Basically you should be able to set tabindex on each input you want to focusable via the tab key. Start the first one a 1 and just count upwards for each input. If you also want to take an input out of focusing via the tab key set the tabindex to -1.
Is there any way to add custom button to the Google Maps using their latest api, so that it will use the same style as other standard buttons? I'd be thankful for a sample code demonstrating the solution.
There's no default class that you can apply or anything else. You'll have to follow up development and change your styling when Google Maps changes it.
For the current version:
MarkUp
<div class="gmnoprint custom-control-container">
<div class="gm-style-mtc">
<div class="custom-control" title="Click to set the map to Home">Home</div>
</div>
</div>
CSS
.custom-control-container {
margin: 5px;
}
.custom-control {
cursor: pointer;
direction: ltr;
overflow: hidden;
text-align: center;
position: relative;
color: rgb(0, 0, 0);
font-family: "Roboto", Arial, sans-serif;
-webkit-user-select: none;
font-size: 11px !important;
background-color: rgb(255, 255, 255);
padding: 1px 6px;
border-bottom-left-radius: 2px;
border-top-left-radius: 2px;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, 0.14902);
-webkit-box-shadow: rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px;
box-shadow: rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px;
min-width: 28px;
font-weight: 500;
}
.custom-control:hover {
font-weight: 900 !important;
}
Here's a jsFiddle that does exactly this. Some of the style attributes still get applied directly by maps. What's not getting applied is cursor: pointer; and some styles might need !important as suffix so it doesn't get overridden by maps.
Keep in mind that you can already add a visual refresh (sneak preview for the new maps styles) with
google.maps.visualRefresh = true;
You might have to refresh when this gets the default.