Unable to scroll through icons carousel - css

I am making an Airbnb clone. I am unable to make this locations filter carousel work. The carousel either takes up more space in the x-axis or if I use overflow: hidden, I am unable to make the hidden icons display on scrolling. Please find the code below.
function LocationFilter() {
const slide = (e) => {
console.log(e);
let handle = e.target.className.baseVal;
let leftHandle = document.querySelector(".left-handle");
console.log(handle);
let locations = document.querySelector(".locations");
let cs = getComputedStyle(locations);
let locationsIndex = parseInt(cs.getPropertyValue("--locations-index"));
if(handle == "right-handle") {
locations.style.setProperty("--locations-index", locationsIndex + 5);
} else {
if(locationsIndex - 5 > 0) {
locations.style.setProperty("--locations-index", locationsIndex - 5);
}
}
// console.log("locationsIndex: ", locationsIndex);
if(locationsIndex > 0) {
leftHandle.style.setProperty("display", "flex");
}
}
return (
<div className='location-filter-container'>
<RiArrowLeftSLine className="left-handle" onClick={(e) => slide(e)} />
<div className="locations snaps-inline">
{
locationData.map((data, index) => (
<button id={index} className="btn">
<img src={data.link} />
<span>{data.desc}</span>
</button>
))
}
</div>
<RiArrowRightSLine className="right-handle" onClick={(e) => slide(e)} />
<div className="location-filters-flex">
<div className="location-filters">
<RiEqualizerLine />
<span>Filters</span>
</div>
</div>
</div>
)
}
export default LocationFilter;
//CSS
.location-filter-container {
display: flex;
align-items: center;
padding: 10px 20px;
margin: 20px auto;
height: 80px;
column-gap: 10px;
background: whitesmoke;
}
.location-filter-container > .locations {
--locations-index: 0;
width: 100%;
max-width: 100%;
display: flex;
flex: 1;
column-gap: 50px;
align-items: center;
justify-content: space-between;
overflow-x: hidden;
overscroll-behavior-inline: contain;
transform: translateX(calc(var(--locations-index) * -10%));
transition: transform .5s ease-in-out;
}
Please find the screenshot below.
enter image description here

Related

Google Places Auto Complete making input field go up

I am working with the react-places-autocomplete package.
Whenever I type text into the input field and get suggestions, it makes the whole input field jumps up, ruining the look.
How can I get the input field to stay in place and just have the suggestions drop down normally? I've tried adding a position: relative and top: Npx style to the suggestions, but that doesn't stop the input field from jumping up.
Searchbar.js
return (
<div className="search">
<PlacesAutocomplete
value={locationChars}
onSelect={handleSelect}
searchOptions={{ types: ["(cities)"] }}
onChange={handleChange}
>
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div>
<input
ref={inputRef}
{...getInputProps({ placeholder: "Search Location" })}
className="search-input"
/>
<div className="suggestions-container">
{loading ? <div>Loading...</div> : null}
{suggestions.map((suggestion) => {
const style = {
backgroundColor: suggestion.active ? "#41b6e6" : "white",
};
return (
<div {...getSuggestionItemProps(suggestion, { style })}>
{suggestion.description}
</div>
);
})}
</div>
</div>
)}
</PlacesAutocomplete>
<SearchIcon className="search-icon" />
</div>
Searchbar.css
.search {
display: flex;
flex: 1;
align-items: center;
border-radius: 24px;
background-color: purple;
margin-right: 1rem;
color: black;
opacity: 1 !important;
}
.search-input {
height: 12px;
padding: 10px;
border: none;
width: 100%;
}
.search-icon {
padding: 5px;
height: 22px !important;
background-color: blue;
}
.suggestions-container
}
Just a guess but you might want to do something with the suggestions-container class. I recently found react-google-autocomplete to be a very smooth experience btw. Happy Hacking!

How can i make slider animation?

I need to make the vertical slider animation ( dots and line ) as in this pic
i managed to do the Accordion and the dots but i don't know how i will going to implement it ( i'm using pseudo )
**my accordion component Where i define the logic of my nested accordions as in images based on array of data **
function MultiLevelAccordion({
data,
bodyClass,
headerClass,
wrapperClass,
renderHeader,
renderContent,
}) {
const RootAccordionId = 'parent-0';
const [accordionsStates, setActiveCardsIndex] = useMergeState({});
const onAccordionToggled = (id, activeEventKey) => {
console.log(activeEventKey);
setActiveCardsIndex({
[id]: activeEventKey ? Number(activeEventKey) : activeEventKey
});
};
console.log('data', data);
const accordionGenerator = (data, parentId) => {
return map(data, (item, index) => {
const active = accordionsStates[parentId] === index;
const hasChildren = item.hasOwnProperty('children') && isArray(item.children) && !isEmpty(item.children);
const isRootAccordion = RootAccordionId === parentId;
const isLastNestedAccordion = !isRootAccordion && !hasChildren;
const accordion = (
<Card className={classNames(wrapperClass, {
'nested-root-accordion': !isRootAccordion,
'last-nested-root-accordion': isLastNestedAccordion,
'multi-level-accordion': !isLastNestedAccordion
})}
>
<Accordion.Toggle
{...{ ...item.id && { id: item.id } }}
onClick={() => this}
as={Card.Header}
eventKey={`${index}`}
className={'cursor-pointer d-flex flex-column justify-content-center'}
>
<div className="d-flex justify-content-between align-items-center">
{renderHeader(item, hasChildren)}
<img
style={{
transition: 'all .5s ease-in-out',
transform: `rotate(${active ? 180 : 0}deg)`
}}
src={setIcon('arrow-down')}
className="ml-2"
alt="collapse"
/>
</div>
</Accordion.Toggle>
<Accordion.Collapse eventKey={`${index}`}>
<Card.Body
className={`accordion-content-wrapper ${!hasChildren ? 'accordion-children-body' : ''} ${bodyClass}`}
>
{!hasChildren ? renderContent(item, hasChildren) : (
<Accordion onSelect={activeEventKey => onAccordionToggled(`${parentId}-${index}`, activeEventKey)}>
<Fade cascade top when={active}>
{accordionGenerator(item.children, `${parentId}-${index}`)}
</Fade>
</Accordion>
)}
</Card.Body>
</Accordion.Collapse>
</Card>
);
return isRootAccordion ? accordion : (
<div className={'d-flex align-items-center'}>
{accordion}
<div className="accordion-indicator-wrapper">
<div className="accordion-indicator" id={`indicator-${parentId}-${index}`} />
</div>
</div>
);
});
};
if (!isArray(data)) {
return;
}
return (
<Accordion onSelect={activeEventKey => onAccordionToggled(RootAccordionId, activeEventKey)}>
{accordionGenerator(data, RootAccordionId)}
</Accordion>
);
}
export default MultiLevelAccordion;
the styles used in scss
.faqs-questions-wrapper {
padding: 20px 10px
}
.faqs-q-count {
color: $black-color;
font-size: calc(1rem - 1rem/8)
}
.faqs-q-a-wrapper {
flex-basis: 95%;
}
.faq-child-title {
color: $black-color
}
.nested-root-accordion {
flex-basis: 90%;
}
.accordion-indicator-wrapper {
flex-basis: 10%;
width: 100%;
display: flex;
justify-content: center;
.accordion-indicator {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: $theme-color;
position: relative;
}
}
Any clue?
Thanks in Advance.
React JS is gonna make this easy
The lines expansion will need to be coded based on the height of the box window
For the dropdown container keep the vertical button lines in a separate div than the Accordian
Check out this pen for creating lines between buttons
https://codepen.io/cataldie/pen/ExVGjya
css part:
.status-container{
padding:10px;
margin:10px;
position:relative;
display: inline-block;
}
.bullet{
padding:0px;
margin:0px;
display: inline-block;
z-index: 10;
}
.bullet:before {
content: ' \25CF';
font-size: 5em;
}
.bullet-before{
/*position:relative;
right:-12px;*/
}
.bullet-after{
/*position:relative;
left:-30px;*/
}
.line{
stroke:blue;
stroke-width:0.3em;
padding:0px;
margin:0px;
display: inline-block;
}
.line-on{
stroke:red;
}
.line-off{
stroke:gray;
}
.color-on{
color: red;
}
.color-off{
color: gray;
}
https://codepen.io/emwing/pen/LgzJOx
I think you can use some inspiration here

How to expand and collapse each list item using react?

i want to display a list of items in the side panel. If the height of content in list item exceeds 36px i want to hide the contents fitting more than 36px and show expand button for that list item (whose content exceeded 36px) and clicking expand button should show the whole content of list item.
What i have tried so far?
I have added a ref to the span element containing the text that overflows. and expand button appears if height of span element exceeds 36px and clicking expand button shows the content for the list item.
The problem now?
It works fine. except that expand buttons are added at the end of all list items....i want them to be shown at the bottom of that particular list item whose content exceeds 36px.
It works like in image below.
Below is the code,
switch (notification.type) {
case 'new_model_uploaded':
return (
<Notification
icon={<SvgProject width="26" height="26"/>}
text={<Text
base_height={36}
name={name}
text=' created'
item_name={itemname}/>}
timestamp={notification.timestamp}>
<div className="additional_details">
<Image
width={70}
height={70}
item_id={filtered_item.id}
/>
</div>
</Notification>
);
case 'deleted':
return (
<List
icon={<Svg width="20" height="22"/>}
text={<Text
base_height={36}
name={list.name}
text=' deleted item '
item_name={itemname}/>}
timestamp={item.timestamp}/>
);
default:
return null;
}
function List(props) {
return (
<li className="list">
<div className="details_container">
<div className="details">
{props.icon}
{props.text}
<Time>{props.timestamp}</Time>
</div>
{props.children}
</div>
</li>
);
}
class Text extends React.PureComponent {
constructor(props) {
super(props);
this.span_ref = React.createRef();
this.state = {
expanded: false,
overflow: false,
};
}
componentDidMount () {
if (this.span_ref.current.offsetHeight <
this.span_ref.current.scrollHeight) {
this.setState({overflow: true});
}
}
set_expanded = () => {
this.setState({expanded: !this.state.expanded});
};
render () {
return (
<span ref={this.span_ref} className={this.props.classname}
style={{overflow: 'hidden', height: (this.state.expanded ?
null : this.props.base_height)}}>
<span className="red">{name}</span> {this.props.text}
<span className="red">{this.props.name}
{this.props.item_name}</span>
{this.props.additional_text}
{this.state.overflow && <button onClick={this.set_expanded}
style={{position: 'absolute', bottom:
0}}>expand</button>}
</span>
);
}
}
.list {
display: flex;
flex-direction: row;
font-size: 12px;
padding: 8px;
min-height: 49px;
li {
list-style: none;
}
.details_container {
display: flex;
flex-direction: column;
flex-grow: 1;
margin-right: 8px;
.details {
display: flex;
color: #333;
align-items: center;
justify-content: center;
flex-grow: 1;
svg {
margin-right: 8px;
margin-left: 7px;
flex: 0 0 auto;
align-self: center;
flex-shrink: 0;
}
span {
flex-grow: 1;
}
time {
flex: 0 0 auto;
margin-left: 8px;
padding-top: 2px;
color: #CCCCCC;
}
}
span {
word-break: break-all;
}
}
}

How to fix v-align styling for imgs with different sizes in Vue.js transition-group?

I prepared example of image slider what I need.
I encounter with styling issue when using images with various dimensions. When element leaving the array, its location is set as absolute value, what is necessary for smooth transition, tho, but the image is also moved up.
I would like to have nice vertical align into middle even leave or enter the array, but could not get on any way.
Another issue, what I would like to solve is when left the window and then went back after a while. The animation running all cycles at once to reach current state instead just stop animation and run after. Maybe it is my responsibility, but browsers doesn't offer nice event to catch blur window or am I wrong?
According to this discussion
Thank you for any ideas.
let numbers = [{key:1},{key:2},{key:3},{key:4},{key:5},{key:6},{key:7}]
let images = [
{ key:1,
src:"http://lorempixel.com/50/100/sports/"},
{ key:2,
src:"http://lorempixel.com/50/50/sports/"},
{ key:3,
src:"http://lorempixel.com/100/50/sports/"},
{ key:4,
src:"http://lorempixel.com/20/30/sports/"},
{ key:5,
src:"http://lorempixel.com/80/20/sports/"},
{ key:6,
src:"http://lorempixel.com/20/80/sports/"},
{ key:7,
src:"http://lorempixel.com/100/100/sports/"}
]
new Vue({
el: '#rotator',
data: {
items: images,
lastKey: 7,
direction: false
},
mounted () {
setInterval(() => {
if (this.direction) { this.prevr() } else { this.nextr() }
}, 1000)
},
methods: {
nextr () {
let it = this.items.shift()
it.key = ++this.lastKey
this.items.push(it)
},
prevr () {
let it = this.items.pop()
it.key = ++this.lastKey
this.items.unshift(it)
}
}
})
.litem {
transition: all 1s;
display: inline-block;
margin-right: 10px;
border: 1px solid green;
background-color: lightgreen;
padding: 10px 10px 10px 10px;
height: 100px;
}
.innerDiv {
border: 1px solid red;
}
.container {
overflow: hidden;
white-space: nowrap;
height: 250px;
border: 1px solid blue;
background-color: lightblue;
}
.list-enter {
opacity: 0;
transform: translateX(40px);
}
.list-leave-to {
opacity: 0;
transform: translateX(-40px);
}
.list-leave-active {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.js"></script>
<div id="rotator">
<button #click="direction = !direction">
change direction
</button>
<transition-group
name="list"
tag="div"
class="container">
<div
v-for="item in items"
:key="item.key" class="litem">
<!--
<div
class='innerDiv'>
{{ item.key }}
</div>
-->
<div class='innerDiv'>
<img :src='item.src'>
</div>
</div>
</transition-group>
</div>
It tooks a while but on the end I think that I have got better result for sliding animation with changing direction feature.
One annoying think is when I swithing the sliding direction so animation is for a 'microsecond' changed to next state and than return to correct one, after it the animation continue as expected. It is happening only in one direction and I don't know how to fix it. Also last box behave differently too only once. No clue at all.
So just 98% solution :-)
let images = [
{key:1, domKey:1, src:"http://lorempixel.com/50/100/sports/" },
{key:2, domKey:2, src:"http://lorempixel.com/50/50/sports/" },
{key:3, domKey:3, src:"http://lorempixel.com/100/50/sports/" },
{key:4, domKey:4, src:"http://lorempixel.com/20/30/sports/" },
{key:5, domKey:5, src:"http://lorempixel.com/80/20/sports/" },
{key:6, domKey:6, src:"http://lorempixel.com/20/80/sports/" },
{key:7, domKey:7, src:"http://lorempixel.com/100/100/sports/" }
]
let setPositionRelative = el => el.style.position = "relative"
new Vue({
el: '#rotator',
data: {
items: images,
lastKey: 7,
direction: true,
changeDirectionRequest: false
},
mounted () {
Array.from(this.$el.querySelectorAll("div[data-key]")).map(setPositionRelative)
setInterval(() => {
if(this.changeDirectionRequest) {
this.changeDirectionRequest = false
this.direction = !this.direction
if (this.direction)
Array.from(this.$el.querySelectorAll("div[data-key]")).map(setPositionRelative)
else
Array.from(this.$el.querySelectorAll("div[data-key]")).map(el => el.style.position = "")
}
if (this.direction) this.prevr()
else this.nextr()
}, 1000)
},
methods: {
nextr () {
let it = this.items.shift()
it.key = ++this.lastKey
this.items.push(it)
},
prevr () {
let it = this.items.pop()
it.key = ++this.lastKey
this.items.unshift(it)
setPositionRelative(this.$el.querySelector("div[data-domkey='"+it.domKey+"']"))
}
}
})
.container {
overflow: hidden;
white-space: nowrap;
height: 200px;
border: 1px solid blue;
background-color: lightblue;
display: flex;
align-items: center;
}
.innerDiv {
border: 1px solid red;
width: auto;
height: auto;
display:-moz-box;
-moz-box-pack:center;
-moz-box-align:center;
display:-webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;
display:box;
box-pack:center;
box-align:center;
}
.litem {
transition: all 1s;
margin-right: 10px;
border: 1px solid green;
background-color: lightgreen;
padding: 10px 10px 10px 10px;
}
.list2-enter, .list-enter {
opacity: 0;
transform: translateX(40px);
}
.list2-leave-to, .list-leave-to {
opacity: 0;
transform: translateX(-40px);
}
.list-leave-active {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.js"></script>
<div id="rotator">
<button #click="changeDirectionRequest = true">change direction</button>
<transition-group name="list" tag="div" class="container">
<div v-for="item in items"
:key="item.key"
:data-domkey="item.domKey"
class="litem">
<div class='innerDiv'>
<img :src='item.src'>
</div>
</div>
</transition-group>
</div>

Issue when adding effects on Div

In the case I have on toggle button that will bring this "mini drawer" that has some chips,
After pressing the Button
The issue in this case is that this chips just POP on the screen and I need to add some animation like this Drawer http://www.material-ui.com/#/components/drawer, I tried to add the transition and transform on CSS but It wont work
JS Part:
renderChip() {
console.log("1.30");
return this.state.listChip.map( (i, index) => (
<Chip className="chips">
{i.nome}
</Chip>
));
}
toggleList() {
this.setState({
visivel: !this.state.visivel,
});
// (this.state.visivel) ? document.getElementById("push").style.width = "0" : document.getElementById("push").style.width = "10px"};
}
render()
{
return (
<MuiThemeProvider>
<div >
<div className="anchor">
<RaisedButton
label="Label before"
labelPosition="before"
primary={true}
onClick = {this.toggleList}
/>
</div>
<div id="push" className="anchorz" style={(this.state.visivel) ? styles.wrapper : styles.closed} >
{this.renderChip()}
</div>
</div>
</MuiThemeProvider>
);
}
CSS part:
position: fixed;
display: flex;
right: 0;
bottom: 110px;
margin-right: 0;
margin-bottom: 0;
margin-left: 10px;
z-index: 900;
transition: transform 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;*/
overflow-x: hidden;
transition: 0.5s;

Resources