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

refactor: improved provide inject by using a single symbol #434

Merged
merged 9 commits into from
Dec 1, 2024

Conversation

Tofandel
Copy link
Contributor

@Tofandel Tofandel commented Nov 29, 2024

fix(reactivity): use provide to register slides instead of traversing nodes (fixes #433, #350)
fix(reactivity): use computed and watchers where possible instead of manual updates
fix(reactivity): update vModel as soon as we are sliding instead of after the transition (fixes #428)
fix(carousel): update sizes during animations (fixes #338)
fix(carousel): in vertical mode with height auto, calculate the height of the slides automatically
fix(accessibility): make elements inside cloned slides non focusable and increase size of pagination buttons (fixes #346)
fix(accessibility): add arrow keys support when carousel is focused (via tab)
fix(performance): only clone itemsToShow elements instead of all the slides
chore(types): improve typings & add tsc during tests & export properly defined components
chore(package): update scripts in package json with new workflows and make package manager agnostic
fix(package): fix order of browser, require and import
chore(github): add test action for PRs
feat(dev): add development playground

This is quite the big refactor but I couldn't really split this into multiple PRs.
There is no breaking change on the api side.
Feel free to use the new playground to experiment (we could also add it to the docs)

fix(reactivity): use provide to register slides instead of traversing nodes
fix(reactivity): use computed and watchers where possible instead of manual updates
fix(reactivity): update vModel as soon as we are sliding instead of after the transition
fix(carousel): update sizes during animations
fix(carousel): in vertical with height auto, calculate the height of the slides automatically
fix(accessibility): make elements inside cloned slides non focusable and increase size of pagination buttons
fix(performance): only clone itemsToShow elements instead of all the slides
chore(types): improve typings & add tsc during tests
chore(package): update scripts in package json with new workflows and make package manager agnostic
fix(package): fix order of browser, require and import
chore(github): add test action for PRs
feat(dev): add development playground
@ismail9k
Copy link
Owner

Hi @Tofandel,

Thank you so much for this extensive PR and all the effort you’ve put into it! 🎉 I can see how much thought went into these fixes and improvements, and I appreciate the attention to reactivity, and performance.

I’ll review the changes in detail and experiment with the new playground soon. However, I want to flag that some of this work may overlap or conflict with updates I’m currently working on in another branch. I’ll take the necessary steps to reconcile those changes as part of the review process.

Thanks again for contributing so much value. I’ll do my best to handle this in a way that aligns with the project’s goals.

@Tofandel
Copy link
Contributor Author

Thanks, I'm sure there could be some conflicts because it's extensive changes, but I still tried to keep it to a minimum while covering as much as I could

Don't hesitate to ping me on the code if you need some explanations

Copy link
Owner

@ismail9k ismail9k left a comment

Choose a reason for hiding this comment

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

Thank you for your hard work on this PR! I’ve gone through the changes (although it was quite hard due to the PR size), but I believe your changes are a great addition and in the right direction. I’ve added some feedback.

src/components/Carousel.ts Outdated Show resolved Hide resolved
playground/App.vue Show resolved Hide resolved
}
},
setup(props: IconProps) {
const carousel = inject(injectCarousel, null)
Copy link
Owner

Choose a reason for hiding this comment

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

Let's keep constant across the different component

Suggested change
const carousel = inject(injectCarousel, null)
const carousel = inject(injectCarousel)
if (!carousel) {
return null // Don't render, let vue warn about the missing provide
}

Copy link
Contributor Author

@Tofandel Tofandel Nov 29, 2024

Choose a reason for hiding this comment

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

In this case, this was so this component could be used standalone outside of a carousel, since this is an exported component and the previous behavior was to allow that, if we don't provide a default value, vue will warn without the injected value and not render, so this would be a breaking change

Users could be using this for example to have their own controls outside of the carousel while keeping the lib icons

This also gave me an idea for an improvement, we could make Pagination and Navigation get a ref to the carousel and get the injection from the ref, to allow them to be outside of a carousel but still control it as well, for a future PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added tests for this component

src/components/Icon.ts Outdated Show resolved Hide resolved
src/utils/getSlidesVNodes.ts Show resolved Hide resolved
src/components/Carousel.ts Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
Co-authored-by: Ismail9k  <dev@ismail9k.com>
package.json Outdated Show resolved Hide resolved
@ismail9k ismail9k self-requested a review November 29, 2024 12:35
@ismail9k ismail9k self-assigned this Nov 29, 2024
Copy link
Contributor Author

@Tofandel Tofandel left a comment

Choose a reason for hiding this comment

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

Forgot to submit my comments, dammit

src/components/Carousel.ts Outdated Show resolved Hide resolved
}
},
setup(props: IconProps) {
const carousel = inject(injectCarousel, null)
Copy link
Contributor Author

@Tofandel Tofandel Nov 29, 2024

Choose a reason for hiding this comment

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

In this case, this was so this component could be used standalone outside of a carousel, since this is an exported component and the previous behavior was to allow that, if we don't provide a default value, vue will warn without the injected value and not render, so this would be a breaking change

Users could be using this for example to have their own controls outside of the carousel while keeping the lib icons

This also gave me an idea for an improvement, we could make Pagination and Navigation get a ref to the carousel and get the injection from the ref, to allow them to be outside of a carousel but still control it as well, for a future PR

src/utils/getSlidesVNodes.ts Show resolved Hide resolved
src/components/Carousel.ts Outdated Show resolved Hide resolved
:gap="10"
:height="height || 'auto'"
:height="parseInt(height) || 'auto'"
Copy link
Contributor Author

@Tofandel Tofandel Nov 29, 2024

Choose a reason for hiding this comment

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

I added something to handle this correctly on the component side lower (|| parseInt(config.height).toString() === config.height),

This allows for other values like 30vh or 10%


// Calculate size based on orientation
const { width, height } = viewport.value.getBoundingClientRect()
Copy link
Contributor Author

@Tofandel Tofandel Nov 29, 2024

Choose a reason for hiding this comment

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

The idea was that if we have a number height specified, we already know the height in pixels, so we don't need to call getBoundingClientRect which is a call that can force a reflow, so more performant

Copy link
Contributor Author

@Tofandel Tofandel Nov 29, 2024

Choose a reason for hiding this comment

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

The multiplier there was part of the animation check, without it the width inside a transform will not be properly calculated (you can see this in the playground during the animation)

@Tofandel
Copy link
Contributor Author

Tofandel commented Nov 29, 2024

I forgot to submit my comment on your review (this interface is always confusing with just the "pending" labels), which is why you didn't see them before you updated the files

I reverted some of your changes accordingly

@Tofandel Tofandel force-pushed the master branch 3 times, most recently from 913f099 to ae1bcb2 Compare November 29, 2024 13:02
@ismail9k ismail9k merged commit 22b1e65 into ismail9k:master Dec 1, 2024
2 checks passed
ismail9k added a commit that referenced this pull request Dec 8, 2024
 The change was found to cause issues during static site generation processes, particularly with frameworks like VitePress.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants