Skip to content

Commit f122049

Browse files
committed
implement draggable menu feature; enhance external data fetching and styling
1 parent 67c575f commit f122049

File tree

4 files changed

+116
-12
lines changed

4 files changed

+116
-12
lines changed

src/lib/components/FetchEaternalData.svelte

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,35 @@
1111
1212
// Import Transition
1313
import { fade } from 'svelte/transition';
14+
import '$lib/styles/draggable.scss';
15+
import { onMount } from 'svelte';
16+
import draggableContainer from '$lib/components/draggableContainer.js';
17+
onMount(async () => {
18+
try {
19+
await restaurantMenu();
20+
draggableContainer('draggableContainer');
21+
} catch (error) {
22+
console.error('Error fetching restaurant menu:', error);
23+
}
24+
});
1425
</script>
1526

1627
{#snippet resMenu(data)}
17-
<div class="container mt-4" in:fade>
18-
<div class="row g-3">
28+
<div class="draggableOuterContainer container mt-4" in:fade>
29+
<div id="draggableContainer" class="row g-2 draggableContainer pb-lg-0 pb-3">
1930
{#each data.menu as { name, price, description, image, category }, index ('resmenu-' + index)}
20-
<div class="col-6 col-md-4 col-lg-3">
31+
<div class="draggableItem">
2132
<div class="card h-100">
2233
<img
2334
src="https://raw.githubusercontent.com/saaqi/restaurant-mobile-app-react-native/refs/heads/main/assets/menu/{image}"
2435
class="card-img-top"
2536
alt={name}
26-
loading='lazy'
37+
loading="lazy"
38+
draggable="false"
2739
/>
2840
<div class="card-body">
2941
<h4 class="card-title mb-3">{name}</h4>
30-
<p class="card-text">{description}</p>
42+
<p class="card-text shortDescription">{description}</p>
3143
</div>
3244
<div class="card-footer">
3345
<div class="row align-items-center justify-content-between">
@@ -57,3 +69,15 @@
5769
{:catch error}
5870
{alert(error + ' - Error Fetching Restaurant Menu')}
5971
{/await}
72+
73+
<style>
74+
.shortDescription {
75+
display: -webkit-box;
76+
-webkit-line-clamp: 2;
77+
-webkit-box-orient: vertical;
78+
overflow: hidden;
79+
text-overflow: ellipsis;
80+
line-clamp: 2;
81+
max-height: 3em;
82+
}
83+
</style>

src/lib/components/Navigation.svelte

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@
1818
});
1919
});
2020
21-
onMount(async () => {
22-
// Only runs in browser
23-
// await import('bootstrap/js/dist/dropdown.js');
24-
await import('bootstrap/js/dist/collapse.js');
25-
// await import('bootstrap/js/dist/scrollspy.js');
26-
});
27-
2821
// Collapse Bootstrap Navigation on click
2922
function collapseBootstrapMenu() {
3023
const menuButton = document.querySelector('.navbar-toggler');
@@ -34,6 +27,13 @@
3427
navbarCollapse.classList.remove('show');
3528
}
3629
30+
onMount(async () => {
31+
// Only runs in browser
32+
// await import('bootstrap/js/dist/dropdown.js');
33+
await import('bootstrap/js/dist/collapse.js');
34+
// await import('bootstrap/js/dist/scrollspy.js');
35+
});
36+
3737
// Navigation links
3838
// You can add more links here
3939
const navLinks = [
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// function isMobile() {
2+
// const isAndroid = /Android/i.test(navigator.userAgent);
3+
// const isiOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
4+
// return isAndroid || isiOS;
5+
// }
6+
7+
const hasTouchSupport = () => (
8+
'ontouchstart' in window ||
9+
navigator.maxTouchPoints > 0 ||
10+
navigator.msMaxTouchPoints > 0
11+
)
12+
13+
const draggableContainer = selectorID => {
14+
if (hasTouchSupport()) return
15+
16+
const container = document.getElementById(selectorID)
17+
if (!container) return
18+
19+
let isDragging = false
20+
let startX = 0
21+
let scrollLeft = 0
22+
23+
const onMouseDown = e => {
24+
isDragging = true
25+
startX = e.pageX - container.offsetLeft
26+
scrollLeft = container.scrollLeft
27+
container.classList.add('dragging')
28+
}
29+
30+
const onMouseLeaveOrUp = () => {
31+
isDragging = false
32+
container.classList.remove('dragging')
33+
}
34+
35+
const onMouseMove = e => {
36+
if (!isDragging) return
37+
e.preventDefault()
38+
const x = e.pageX - container.offsetLeft
39+
const walk = (x - startX) * 3
40+
container.scrollLeft = scrollLeft - walk
41+
}
42+
43+
container.addEventListener('mousedown', onMouseDown)
44+
container.addEventListener('mouseleave', onMouseLeaveOrUp)
45+
container.addEventListener('mouseup', onMouseLeaveOrUp)
46+
container.addEventListener('mousemove', onMouseMove)
47+
}
48+
export default draggableContainer

src/lib/styles/draggable.scss

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
.draggableContainer {
2+
display: flex;
3+
flex-wrap: wrap;
4+
justify-content: start;
5+
}
6+
.draggableItem {
7+
flex: 0 0 25%;
8+
}
9+
10+
@media (max-width: 992px) {
11+
.draggableContainer {
12+
flex-wrap: nowrap;
13+
overflow-x: auto;
14+
scroll-snap-type: x mandatory;
15+
-webkit-overflow-scrolling: touch;
16+
cursor: grab;
17+
user-select: none;
18+
19+
&.dragging {
20+
cursor: grabbing;
21+
}
22+
}
23+
.draggableItem {
24+
flex: 0 0 48%;
25+
}
26+
}
27+
28+
@media (max-width: 768px) {
29+
.draggableItem {
30+
flex: 0 0 95%;
31+
}
32+
}

0 commit comments

Comments
 (0)