Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Slider #6

Merged
merged 4 commits into from
Dec 19, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 107 additions & 42 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ <h3 class="font-bold font-mono">AirBnB Search Bar:</h3>
showSearch = false;
selectedTab = 'Where';
destination = '';
time = 'Any week';

totalMonths = 12;
checkIn = '';
checkOut = '';

Expand All @@ -48,6 +49,31 @@ <h3 class="font-bold font-mono">AirBnB Search Bar:</h3>

scrollPosition = 'middle';
SCROLL_OFFSET = 128;

function getStartAndEndMonth(totalMonths) {
const today = new Date();
const startMonth = today.getMonth() + 1;
const endMonth = today.getMonth() + 1 + totalMonths;

const startDate = new Date(today.getFullYear(), startMonth, 1);
const endDate = new Date(today.getFullYear(), endMonth, 1);
return [startDate, endDate];
}

function getSliderValue(position) {
const rect = document.querySelector('.slider').getBoundingClientRect();
const dx = position.x - rect.left - rect.width / 2;
const dy = position.y - rect.top - rect.height / 2;
const theta = Math.atan2(dy, dx);
const left = 50 + 50 * Math.cos(theta);
const top = 50 + 50 * Math.sin(theta);
let percentage = (theta + Math.PI / 2) / (2 * Math.PI) * 100;

if (percentage < 0)
percentage += 100;

return { left, top, percentage };
}
</script>

<div class="flex items-center justify-center">
Expand Down Expand Up @@ -213,7 +239,29 @@ <h3 class="font-bold font-mono">AirBnB Search Bar:</h3>
<input
id="time"
type="text"
:value="time"
:value="if (whenSelectedTab === 'Flexible') {
selectedMonths.length
? `${whenHowLong} in ${selectedMonths.join(', ')}`
: `Any ${whenHowLong.toLowerCase()}`
} else if (whenSelectedTab === 'Months') {
const dates = getStartAndEndMonth(totalMonths);
const startDate = dates[0];
const endDate = dates[1];

let date = startDate.toLocaleString('default', {
month: 'short',
year: 'numeric',
day: 'numeric',
});
date += ' - ';
date += endDate.toLocaleString('default', {
month: 'short',
year: 'numeric',
day: 'numeric',
});
} else {
''
}"
class="bg-transparent pointer-events-none text-ellipsis"
disabled
/>
Expand Down Expand Up @@ -371,44 +419,23 @@ <h3 class="font-bold font-mono">AirBnB Search Bar:</h3>
type="button"
class="py-2 px-6 flex items-center justify-center text-sm text-gray-900 font-medium whitespace-nowrap rounded-full cursor-pointer transition-colors duration-100"
:class="whenSelectedTab === 'Dates' ? 'bg-white ring-1 ring-gray-300' : 'hover:bg-gray-300'"
:click="whenSelectedTab = 'Dates'; selectedTab = 'Check In'; time = ''"
:click="whenSelectedTab = 'Dates'; selectedTab = 'Check In';"
>
Dates
</button>
<button
type="button"
class="py-2 px-6 flex items-center justify-center text-sm text-gray-900 font-medium whitespace-nowrap rounded-full cursor-pointer transition-colors duration-100"
:class="whenSelectedTab === 'Months' ? 'bg-white ring-1 ring-gray-300' : 'hover:bg-gray-300'"
:click="whenSelectedTab = 'Months';
selectedTab = 'When';
const today = new Date();
const startMonth = today.getMonth() + 1;
const endMonth = today.getMonth() + 1 + 3;

const startDate = new Date(today.getFullYear(), startMonth, 1);
const endDate = new Date(today.getFullYear(), endMonth, 1);

time = startDate.toLocaleString('default', {
month: 'short',
year: 'numeric',
day: 'numeric',
});
time += ' - ';
time += endDate.toLocaleString('default', {
month: 'short',
year: 'numeric',
day: 'numeric',
});"
:click="whenSelectedTab = 'Months'; selectedTab = 'When';"
>
Months
</button>
<button
type="button"
class="py-2 px-6 flex items-center justify-center text-sm text-gray-900 font-medium whitespace-nowrap rounded-full cursor-pointer transition-colors duration-100"
:class="whenSelectedTab === 'Flexible' ? 'bg-white ring-1 ring-gray-300' : 'hover:bg-gray-300'"
:click="whenSelectedTab = 'Flexible';
selectedTab = 'When';
time = 'Any week'"
:click="whenSelectedTab = 'Flexible'; selectedTab = 'When';"
>
Flexible
</button>
Expand All @@ -426,32 +453,23 @@ <h3 class="font-bold font-mono">AirBnB Search Bar:</h3>
type="button"
class="py-2 px-4 text-base text-gray-900 rounded-full"
:class="whenHowLong === 'Weekend' ? 'ring-2 ring-gray-900' : 'ring-1 ring-gray-200'"
:click="whenHowLong = 'Weekend';
time = selectedMonths.length
? `Weekend in ${selectedMonths.join(', ')}`
: 'Any weekend'"
:click="whenHowLong = 'Weekend';"
>
Weekend
</button>
<button
type="button"
class="py-2 px-4 text-base text-gray-900 rounded-full"
:class="whenHowLong === 'Week' ? 'ring-2 ring-gray-900' : 'ring-1 ring-gray-200'"
:click="whenHowLong = 'Week';
time = selectedMonths.length
? `Week in ${selectedMonths.join(', ')}`
: 'Any week'"
:click="whenHowLong = 'Week';"
>
Week
</button>
<button
type="button"
class="py-2 px-4 text-base text-gray-900 rounded-full"
:class="whenHowLong === 'Month' ? 'ring-2 ring-gray-900' : 'ring-1 ring-gray-200'"
:click="whenHowLong = 'Month';
time = selectedMonths.length
? `Month in ${selectedMonths.join(', ')}`
: 'Any month'"
:click="whenHowLong = 'Month';"
>
Month
</button>
Expand Down Expand Up @@ -495,10 +513,7 @@ <h3 class="font-bold font-mono">AirBnB Search Bar:</h3>
type="button"
class="h-36 w-28 flex flex-col items-center justify-center gap-1 text-center text-gray-900 rounded-2xl"
:class="selectedMonths.includes(month) ? 'ring-2 ring-gray-900' : 'ring-1 ring-gray-200'"
:click="selectedMonths = selectedMonths.toggle(month);
time = selectedMonths.length
? `${whenHowLong} in ${selectedMonths.join(', ')}`
: `Any ${whenHowLong[0].toLowerCase() + whenHowLong.slice(1)}`"
:click="selectedMonths = selectedMonths.toggle(month);"
>
<span :class="selectedMonths.includes(month) ? 'text-gray-900' : 'text-gray-600'">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-10 h-10" : aria-hidden="true">
Expand Down Expand Up @@ -535,6 +550,56 @@ <h3 class="font-bold font-mono">AirBnB Search Bar:</h3>
<div class="text-lg font-medium text-gray-900">
When's your trip?
</div>

<style>
.slider-fill:before {
background: conic-gradient(var(--fill-color) calc(var(--percentage)*1%), #0000 0);
}
</style>

<!-- Slider -->
<div class="slider-container relative shadow-inset rounded-full" style="width: 230px; height: 230px;">
<!-- Slider Fill -->
<div
class="slider-fill absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full aspect-square inline-grid place-content-center bg-gray-200 rounded-full before:content-[''] before:absolute before:rounded-full before:inset-0"
style="--percentage: 100; --fill-color: #e11d48"
aria-hidden="true"
></div>

<!-- Slider with Handle -->
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<div
class="slider relative"
style="width: 200px; height: 200px;"
:mousedown="mousedown = true"
:mouseup="mousedown = false"
:mousemove="if (mousedown) {
const value = getSliderValue({
x: event.clientX,
y: event.clientY,
});

totalMonths = Math.round(value.percentage / 100 * 12) === 0
? 12
: Math.round(value.percentage / 100 * 12);

$('.slider-fill').style.setProperty('--percentage', value.percentage);
$('.slider-handle').style.left = `${value.left}%`;
$('.slider-handle').style.top = `${value.top}%`;
}"
>
<div class="slider-circle relative w-full h-full rounded-full">
<div class="slider-handle absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white rounded-full ring-2 ring-rose-500" style="width:25px; height:25px"></div>
</div>
</div>
</div>

<!-- Slider Label -->
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 h-3/4 w-3/4 flex flex-col items-center justify-center bg-white rounded-full shadow-lg pointer-events-none">
<span class="slider-label text-6xl font-bold" :text="totalMonths"></span>
<span class="text-base font-bold">months</span>
</div>
</div>
</div>

</div>
Expand Down
Loading