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

Mobile drag issues #396

Open
tutods opened this issue Dec 23, 2023 · 2 comments
Open

Mobile drag issues #396

tutods opened this issue Dec 23, 2023 · 2 comments

Comments

@tutods
Copy link

tutods commented Dec 23, 2023

Hi.
I'm trying to do a slide with some cards, but in mobile isn't working.

keen-slider.mp4

I have other sliders, but using images and it's ok, only this one I can't put it working.

My code:

'use client';

import { useMemo } from 'react';

import type { KeenSliderOptions } from 'keen-slider/react';

import { ProjectCard } from '@components/cards';
import { CarouselDot } from '@components/carousels/partials/Dot';
import { useCarousel } from '@hooks/useCarousel';
import type { HighlightedProjectsType } from '@shared/types';
import { cn } from '@utils';

type Props = {
  projects: HighlightedProjectsType;
  className?: string;
};

const SLIDER_OPTIONS = (totalLength: number): Partial<KeenSliderOptions> => ({
  breakpoints: {
    '(max-width: 768px)': {
      loop: true,
      mode: 'free-snap',
      slides: {
        number: totalLength,
        perView: 1,
        spacing: 10,
      },
    },
    '(min-width: 769px)': {
      loop: false,
      slides: {
        number: totalLength / 3,
        perView: 3,
        spacing: 10,
      },
    },
  },
  initial: 0,
  mode: 'snap',
  renderMode: 'performance',
  slides: {
    origin: 'auto',
  },
});

export const ProjectCarousel = ({ className = '', projects }: Props) => {
  const { currentSlide, instanceRef, loaded, sliderRef } = useCarousel(
    SLIDER_OPTIONS(projects.length),
  );

  const slidesLength = useMemo(
    () => instanceRef?.current?.track.details?.slides?.length ?? projects.length,
    [projects, instanceRef],
  );

  return (
    <section className={cn('flex flex-col gap-2 max-w-full', className)}>
      <div
        className="keen-slider flex cursor-grab justify-end gap-2.5"
        data-aos="fade-left"
        ref={sliderRef}
      >
        {projects.map(project => (
          <ProjectCard key={project._id} className="keen-slider__slide" {...project} />
        ))}
      </div>

      {loaded && !!instanceRef.current && (
        <nav className="flex items-center justify-end gap-2" data-aos="fade-left">
          {[...Array(slidesLength).keys()].map(idx => (
            <CarouselDot
              key={idx}
              id={idx}
              isCurrentSlide={currentSlide === idx}
              variant="light"
              onClick={() => {
                instanceRef.current?.moveToIdx(idx);
              }}
            />
          ))}
        </nav>
      )}
    </section>
  );
};
@tutods
Copy link
Author

tutods commented Dec 23, 2023

The ProjectCard component is very simple:

import Link from 'next/link';

import { Button } from '@components/buttons';
import { OptimizedImage } from '@components/images/OptimizedImage';
import { SpriteCategories } from '@enums';
import type { BasePageWithImageSelectionType } from '@shared/types/selections/Common';
import { cn } from '@utils/cn';

type Props = BasePageWithImageSelectionType & {
  className?: string;
};

export const ProjectCard = ({ className = '', headline, image, slug, title, ...props }: Props) => (
  <Link
    passHref
    className={cn('group', className)}
    data-aos="fade-up"
    href={`/projects/${slug}`}
    {...props}
  >
    <article className="relative isolate h-full min-h-[400px] w-full overflow-hidden rounded-lg shadow-sm lg:h-80">
      <OptimizedImage
        fill
        alt={title}
        className="-z-10 object-cover object-center transition-all duration-500 ease-in-out group-hover:scale-125"
        image={image}
      />

      <div className="absolute inset-0 -z-10 bg-gradient-to-b from-transparent to-zinc-900" />

      <div className="mt-auto flex h-full flex-col justify-end px-4 py-6 text-zinc-200">
        <h3 className="mb-1 text-lg font-semibold text-zinc-50">{title}</h3>
        {!!headline && <p className="line-clamp-3 text-sm">{headline}</p>}

        <Button
          className="mt-4 max-w-fit"
          variant="text"
          icon={{
            category: SpriteCategories.ARROWS,
            name: 'arrow-narrow-right',
            position: 'suffix',
          }}
        >
          Ver mais
        </Button>
      </div>
    </article>
  </Link>
);

@tutods
Copy link
Author

tutods commented Dec 23, 2023

The problem is solved, basically the problem is the display: flex.
But now I have other problem.

'(min-width: 769px)': {
        loop: false,
        slides: {
          number: Math.ceil(projects.length / 2),
          perView: 2,
          spacing: 10,
        },
      },

If I use this number on slides to help me with navigation bullets (for example have 3 slides, should show 2 bullets - so length / 2), the slides appear this way:
image

  • the third slide don't work and the same for the bullets pagination

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant