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

Make scrolling more generic #201

Merged
merged 4 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
18 changes: 13 additions & 5 deletions Sources/DesignSite/DesignTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -369,15 +369,15 @@ private struct VaporThemeHTMLFactory: HTMLFactory {
image: "/images/sambot-card.png",
description: "Sambot helps all members of a Mobile App Dev Team to be more productive, reactive and efficient while using Bitrise CI services"
)
}.class("showcase-cards scrolling-wrapper").id("showcase-scrolling-wrapper")
}.class("showcase-cards scrollable").id("home-page-showcase-cards-list")
Div {
Button {
Span().class("vapor-icon icon-arrow-left")
}.class("arrow-button").onclick("scrollToLeft()")
}.class("arrow-button left-scroll-button")
Button {
Span().class("vapor-icon icon-arrow-right")
}.class("arrow-button").onclick("scrollToRight()")
}.class("btn-group")
}.class("arrow-button right-scroll-button")
}.class("btn-group scroll-button-group").attribute(named: "data-scrollable", value: "home-page-showcase-cards-list")
}.class("row row-cols-1 row-cols-lg-2").id("showcase")
Div {
Div {
Expand Down Expand Up @@ -468,7 +468,15 @@ private struct VaporThemeHTMLFactory: HTMLFactory {
logo: "/images/transeo.png",
description: "Transeo is an educational technology company that builds tracking tools for student planning and data analysis."
)
}.class("sponsors-list")
}.class("sponsors-list").id("home-page-sponsors-list")
Div {
Button {
Span().class("vapor-icon icon-arrow-left")
}.class("arrow-button left-scroll-button")
Button {
Span().class("vapor-icon icon-arrow-right")
}.class("arrow-button right-scroll-button")
}.class("btn-group scroll-button-group").attribute(named: "data-scrollable", value: "home-page-sponsors-list")
}.class("row").id("sponsors")
}.class("container")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public struct ShowcaseCard: Component {
}.class("btn btn-primary mt-auto")
}.class("card-body d-flex flex-column")
}.class("card")
.style("width: 18rem;")
.id("\(name.lowercased().replacingOccurrences(of: " ", with: "-"))-card")
}
}
}
41 changes: 27 additions & 14 deletions src/scss/vapor/main-site.scss
Original file line number Diff line number Diff line change
Expand Up @@ -658,19 +658,13 @@ h2 {
}
}
}
}

.btn-group {
margin-top: 32px;
display: flex;
justify-content: center; // center align horizontally
flex-wrap: wrap; // allow buttons to wrap to next line if necessary
}

@media (min-width: 768px) {
.btn-group {
justify-content: flex-start; // align to left on larger screens
}
}
.row>.scroll-button-group {
margin-top: 32px;
display: flex;
justify-content: center; // center align horizontally
flex-wrap: wrap; // allow buttons to wrap to next line if necessary

.arrow-button {
display: flex;
Expand All @@ -685,15 +679,34 @@ h2 {
width: 56px;
height: 56px;

&:hover {
background: $grey-300;
}

&.disabled {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need dark mode versions of the disabled state

background: $grey-100;
border: 1px solid $grey-200;

span {
background-color: $grey-400;
}

&:hover {
background: $grey-100;
}
}

span {
background-color: $grey-800;
width: 24px;
height: 24px;
}
}
}

.arrow-button:hover {
background: $grey-300;
@media (min-width: 768px) {
.row>.scroll-button-group {
justify-content: flex-start; // align to left on larger screens
}
}

Expand Down
26 changes: 13 additions & 13 deletions src/scss/vapor/vapor-dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,19 @@
}
}

.row>.scroll-button-group .arrow-button {
background: rgba(55, 57, 83, 0.3);
border: 1px solid #373953;

span {
background-color: $grey-200;
}
}

.row>.scroll-button-group .arrow-button:hover {
background: rgba(55, 57, 83, 0.5);
}

#showcase {
.showcase-header {
.btn {
Expand Down Expand Up @@ -580,19 +593,6 @@
}
}

.arrow-button {
background: rgba(55, 57, 83, 0.3);
border: 1px solid #373953;

span {
background-color: $grey-200;
}
}

.arrow-button:hover {
background: rgba(55, 57, 83, 0.5);
}

#sambot-card img {
content: url(../../../static/images/sambot-card-dark.png);
}
Expand Down
99 changes: 86 additions & 13 deletions static/js/mainSiteScrollShowcase.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,90 @@
function scrollToRight() {
var element = document.getElementById("showcase-scrolling-wrapper");
element.scrollBy({
top: 0,
left: 320,
behavior: 'smooth'
});
function isScrollable(element) {
return element.scrollWidth > element.clientWidth;
}

function updateScrollButtonStates(scrollable, leftButton, rightButton) {
const isAtStart = scrollable.scrollLeft === 0;
const isAtEnd = scrollable.scrollLeft + scrollable.clientWidth >= scrollable.scrollWidth - 1; // -1 to account for rounding errors

leftButton.disabled = isAtStart;
rightButton.disabled = isAtEnd;

// Optional: Add/remove a class for styling
leftButton.classList.toggle('disabled', isAtStart);
rightButton.classList.toggle('disabled', isAtEnd);
}

function scrollToLeft() {
var element = document.getElementById("showcase-scrolling-wrapper");
element.scrollBy({
top: 0,
left: -320,
behavior: 'smooth'
function updateScrollButtonVisibility(scrollable, buttonGroup) {
if (isScrollable(scrollable)) {
buttonGroup.style.display = 'flex';
const leftButton = buttonGroup.querySelector(".left-scroll-button");
const rightButton = buttonGroup.querySelector(".right-scroll-button");
updateScrollButtonStates(scrollable, leftButton, rightButton);
} else {
buttonGroup.style.display = 'none';
}
}

function scroll(direction) {
return function (event) {
const buttonGroup = event.target.closest(".scroll-button-group");
const scrollableID = buttonGroup.getAttribute("data-scrollable");
const scrollable = document.getElementById(scrollableID);
const cardWidth = scrollable.querySelector(".card").offsetWidth + 32;

if (scrollable) {
scrollable.scrollBy({
top: 0,
left: direction * cardWidth,
behavior: 'smooth'
});

// Update button states after scrolling
setTimeout(() => {
const leftButton = buttonGroup.querySelector(".left-scroll-button");
const rightButton = buttonGroup.querySelector(".right-scroll-button");
updateScrollButtonStates(scrollable, leftButton, rightButton);
}, 500); // Adjust timeout to match your scroll behavior duration
}
};
}

const scrollToRight = scroll(1);
const scrollToLeft = scroll(-1);

function initializeScrollButtons() {
document.querySelectorAll(".scroll-button-group").forEach(buttonGroup => {
const scrollableID = buttonGroup.getAttribute("data-scrollable");
const scrollable = document.getElementById(scrollableID);

if (scrollable) {
const leftButton = buttonGroup.querySelector(".left-scroll-button");
const rightButton = buttonGroup.querySelector(".right-scroll-button");

updateScrollButtonVisibility(scrollable, buttonGroup);

// Add event listeners to buttons
leftButton.addEventListener("click", scrollToLeft);
rightButton.addEventListener("click", scrollToRight);

// Update visibility and button states on scroll
scrollable.addEventListener('scroll', () => {
updateScrollButtonStates(scrollable, leftButton, rightButton);
});

// Update visibility and button states on window resize
window.addEventListener('resize', () => {
updateScrollButtonVisibility(scrollable, buttonGroup);
});

// Optional: Update visibility and button states when content changes
const observer = new MutationObserver(() => {
updateScrollButtonVisibility(scrollable, buttonGroup);
});
observer.observe(scrollable, { childList: true, subtree: true });
}
});
}

// Call this function when the DOM is ready
document.addEventListener('DOMContentLoaded', initializeScrollButtons);
Loading