Skip to content

Commit

Permalink
feat: migrate the carousel to transforms (#963)
Browse files Browse the repository at this point in the history
* feat: get custom scroll for mouse and update

* refactor: remove drag speed

* refactor: add back drag speed

* feat: one scroll model

* fix: clean up a bit

* fix: dumb timeouts

* without animateScroll$

* does transform walking

* feat: correct drag direction

* initial snapping

* correct snapping

* works with next and prev

* add will change transform

* custom animations except for initial load

* user defined transitions work

* fix: resize

* mobile sorta works

* smoother on mobile

* fix: simplify scroller impl

* narrowed down problem

* mobile working

* handle x, y, or z

* working in an agnostic way

* cleanup markup and props

* get initial slide position

* refactor: add comment on qvisible

* feat: no flicker getting initial slide

* teeny flicker but with animations

* feat: no more flicker

* feat: handle initial slide pos for any orientation

* feat: respect transform boundaries

* fix: carousel start index

* fix: progress

* fix: make sure there are no duplicate handler calls

* fix: respect boundaries

* refactor: make carousel scroller easier to understand

* fix: remove the viewport from the equation

* fix: smoother swiping experience

* feat: sensitivity

* feat: initial move impl

* fix: only calculate pos when it's not the start

* feat: renders correct bullets based on slides per view

* feat: proper bullet navigation

* feat: bullets are smart enough to know if something is in range

* feat: prev and next buttons both work with move

* fix: state tests

* feat: initial vertical

* fix: offset for vertical version

* feat: vertical with transform

* fix: touch start moves according to touchY in vertical

* refactor: better naming

* refactor: code more easy to understand

* refactored names

* refactor: use props map instead

* fix: initial slide position vertically

* fix: don't render marker points with non-scroller carousels

* feat: start docs

* fix: text align

* docs: add example animation

* feat: upgrade carousel to beta

* fix: the merge issues
  • Loading branch information
thejackshelton authored Sep 17, 2024
1 parent f59e183 commit f1ea4f3
Show file tree
Hide file tree
Showing 24 changed files with 1,146 additions and 635 deletions.
2 changes: 1 addition & 1 deletion apps/website/src/_state/component-statuses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const statusByComponent: ComponentKitsStatuses = {
},
headless: {
Accordion: ComponentStatus.Beta,
Carousel: ComponentStatus.Draft,
Carousel: ComponentStatus.Beta,
Collapsible: ComponentStatus.Beta,
Combobox: ComponentStatus.Beta,
Checkbox: ComponentStatus.Draft,
Expand Down
2 changes: 1 addition & 1 deletion apps/website/src/components/feature-list/feature-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const FeatureList = component$((props: FeatureListProps) => {
{!props.issues && (
<Note>
Missing a feature? Check out the{' '}
<a class="font-bold" href="https://qwikui.com/contributing/">
<a class="font-bold" href="https://qwikui.com/docs/contributing/">
contributing guide
</a>{' '}
and we'd be happy to review any relevant issues or PR's. Feel free to work on
Expand Down
10 changes: 3 additions & 7 deletions apps/website/src/routes/docs/contributing/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -379,20 +379,16 @@ Notice how `<ExampleRoot />` returns a `children` prop. This is because inline c
Context and hooks is still easy to use, create a new component called `<ExampleBase />` and return that instead of the div (with the children passed between) in the example above. From there, you can use context, hooks, and all the other Qwik goodies as a top level component.
```tsx
return (
<ExampleBase>
{props.children}
</ExampleBase>
)
return <ExampleBase>{props.children}</ExampleBase>;

// use hooks, context, and other stuff here!
export const ExampleBase = component$(() => {
return (
<div>
<Slot />
</div>
)
})
);
});
```
## That's it!
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { component$, useStyles$ } from '@builder.io/qwik';
import { Carousel } from '@qwik-ui/headless';

export default component$(() => {
useStyles$(styles);

const colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink'];

return (
<Carousel.Root class="carousel-root" gap={30}>
<div class="carousel-buttons">
<Carousel.Previous>Prev</Carousel.Previous>
<Carousel.Next>Next</Carousel.Next>
</div>
<Carousel.Scroller class="carousel-scroller carousel-animation">
{colors.map((color) => (
<Carousel.Slide key={color} class="carousel-slide">
{color}
</Carousel.Slide>
))}
</Carousel.Scroller>
</Carousel.Root>
);
});
// internal
import styles from './carousel.css?inline';
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@
width: 100%;
}

.carousel-scroller {
margin-bottom: 0.5rem;
}

.carousel-slide {
border: 2px dotted hsl(var(--primary));
min-height: 10rem;
max-height: 10rem;
-webkit-user-select: none; /* support for Safari */
user-select: none;
}
Expand All @@ -18,13 +15,15 @@
gap: 0.5rem;
padding: 1rem;
border: 2px dotted hsl(var(--foreground));
margin-top: 0.5rem;
}

.carousel-buttons {
display: flex;
justify-content: space-between;
border: 2px dotted hsl(var(--accent));
margin-bottom: 0.5rem;
margin-bottom: 0.5rem;
}

.carousel-buttons button {
Expand Down Expand Up @@ -76,6 +75,8 @@
.carousel-stepper {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
flex-wrap: wrap;
}

.carousel-step {
Expand All @@ -100,3 +101,7 @@
.carousel-step[data-current]::before {
background-color: hsl(var(--primary));
}

.carousel-animation {
transition: 0.35s transform cubic-bezier(0.57, 0.16, 0.95, 0.67);
}
52 changes: 52 additions & 0 deletions apps/website/src/routes/docs/headless/carousel/examples/move.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { component$, useStyles$ } from '@builder.io/qwik';
import { Carousel } from '@qwik-ui/headless';

export default component$(() => {
useStyles$(styles);

const colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink'];

useStyles$(`
.carousel-circle {
width: 20px;
height: 20px;
margin: 0 5px;
border-radius: 50%;
background-color: lightgray;
}
.carousel-circle[data-active] {
background-color: lightblue;
}
`);

return (
<>
<Carousel.Root class="carousel-root" gap={30} move={2} slidesPerView={2}>
<div class="carousel-buttons">
<Carousel.Previous>Prev</Carousel.Previous>
<Carousel.Next>Next</Carousel.Next>
</div>
<Carousel.Scroller class="carousel-scroller">
{colors.map((color) => (
<Carousel.Slide key={color} class="carousel-slide">
{color}
</Carousel.Slide>
))}
</Carousel.Scroller>

<Carousel.Pagination
style={{ display: 'flex', justifyContent: 'center', marginTop: '0.5rem' }}
>
{colors.map((_, index) => {
return (
<Carousel.Bullet key={index} class="carousel-circle"></Carousel.Bullet>
);
})}
</Carousel.Pagination>
</Carousel.Root>
</>
);
});
// internal
import styles from './carousel.css?inline';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default component$(() => {
useStyles$(styles);

const colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink'];
const selectedIndex = useSignal<number>(0);
const selectedIndex = useSignal<number>(2);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default component$(() => {
const colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink'];

return (
<Carousel.Root class="carousel-root" gap={30} loop>
<Carousel.Root class="carousel-root" gap={30} rewind>
<div class="carousel-buttons">
<Carousel.Previous>Prev</Carousel.Previous>
<Carousel.Next>Next</Carousel.Next>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { component$, useStyles$ } from '@builder.io/qwik';
import { Carousel } from '@qwik-ui/headless';

export default component$(() => {
useStyles$(styles);

const colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink'];

return (
<Carousel.Root
class="carousel-root"
gap={30}
sensitivity={{
mouse: 2.5,
touch: 2.25,
}}
>
<div class="carousel-buttons">
<Carousel.Previous>Prev</Carousel.Previous>
<Carousel.Next>Next</Carousel.Next>
</div>
<Carousel.Scroller class="carousel-scroller">
{colors.map((color) => (
<Carousel.Slide key={color} class="carousel-slide">
{color}
</Carousel.Slide>
))}
</Carousel.Scroller>
</Carousel.Root>
);
});
// internal
import styles from './carousel.css?inline';
30 changes: 30 additions & 0 deletions apps/website/src/routes/docs/headless/carousel/examples/start.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { component$, useStyles$ } from '@builder.io/qwik';
import { Carousel } from '@qwik-ui/headless';

export default component$(() => {
useStyles$(styles);

const colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink'];

return (
<Carousel.Root class="carousel-root" gap={30}>
<div class="carousel-buttons">
<Carousel.Previous>Prev</Carousel.Previous>
<Carousel.Next>Next</Carousel.Next>
</div>
<Carousel.Scroller class="carousel-scroller">
{colors.map((color) => (
<Carousel.Slide
style={{ flexBasis: '300px' }}
key={color}
class="carousel-slide"
>
{color}
</Carousel.Slide>
))}
</Carousel.Scroller>
</Carousel.Root>
);
});
// internal
import styles from './carousel.css?inline';
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ export default component$(() => {
const colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'pink'];

return (
<Carousel.Root class="carousel-root" gap={30} direction="column" maxSlideHeight={160}>
<Carousel.Root
class="carousel-root"
gap={30}
orientation="vertical"
maxSlideHeight={160}
>
<div class="carousel-buttons">
<Carousel.Previous>Prev</Carousel.Previous>
<Carousel.Next>Next</Carousel.Next>
Expand Down
Loading

0 comments on commit f1ea4f3

Please sign in to comment.