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

Slider: RTL support #791

Merged
merged 13 commits into from
Dec 17, 2023
Merged

Conversation

abdel-17
Copy link
Contributor

@abdel-17 abdel-17 commented Dec 3, 2023

Really excited about this pr! 👀

Added two more orientations for sliders, horizontal-rl and vertical-tb, effectively adding RTL support for sliders with an added bonus of top-to-bottom orientation for vertical sliders. I also documented the two orientations.

I manually tested all 4 orientations with and without ticks. Everything seems to be placed correctly and keyboard shortcuts work. I haven't added any automated tests, though.

Copy link

changeset-bot bot commented Dec 3, 2023

🦋 Changeset detected

Latest commit: 65b4cde

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@melt-ui/svelte Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@huntabyte
Copy link
Member

huntabyte commented Dec 3, 2023

Hey @abdel-17 thanks for taking the time to tackle this!

I think a better approach in terms of DX would be to add a dir prop that accepts either 'ltr' | 'rtl' (defaulting to 'ltr'). And then instead of the switch check for all the orientations, we can have the defaults as they were and add a conditional if (dir === 'rtl') and handle the logic differently there!

Alternatively, we could make the prop rtl: boolean!

The reasoning for this is that the orientation doesn't actually change with RTL, but rather the behavior of that orientation, so it doesn't make much sense to couple them like that!

This would clean things up and enable devs to implement things like a "toggle rtl" much easier since we could add that same prop to all other components as we add RTL support and it will be a matter of changing a single prop!

@abdel-17
Copy link
Contributor Author

abdel-17 commented Dec 3, 2023

Hey @huntabyte, dir="rtl" makes sense for horizontal sliders, but what about vertical sliders? dir="rtl" doesn't make sense in that context. Should we add dir="ttb"? What if the user passes orientation="horizontal" and dir="ttb"? If you have any suggestions, I'm willing to modify the code.

@huntabyte
Copy link
Member

huntabyte commented Dec 3, 2023

I know for a fact we should have either a dir or rtl prop, likely rtl to keep it simple which we can apply to basically every builder as we add RTL support and ensure a consistent DX across the builders.

My thinking behind the whole rtl: boolean idea is that I imagine having some sort of app-wide context tracking if the user is in RTL mode. Then you'd just be able to pass that boolean state into all the builders being used across the app, where everything would just work rather than having to jump through hoops on a per-builder basis if that makes sense.

I noticed on Discord you sent the following:

It seems that, for vertical writing modes, "rtl" does affect orientation. "vertical" with ltr is top-down while with rtl it''s bottom-up. I'm thinking we should support vertical sliders that start from the top, but I'm not sure if it should be another prop or not.

With this being the case, then we only really need rtl. If rtl && orientation === 'vertical' we do top to bottom, if horizontal we do right to left. So in this sense it doesn't really mean direction of the slider but instead the mode the user is in 😃

Comment on lines 42 to 43
You can set the `orientation` prop to `horizontal-rl` for right-to-left orientation. Here's an
example:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
You can set the `orientation` prop to `horizontal-rl` for right-to-left orientation. Here's an
example:
To enable Right-to-Left (RTL) support, you can set the `rtl` prop to `true.
Here's an example of a horizontal slider with RTL enabled:

Comment on lines 49 to 50
Top-to-bottom orientation is also supported by setting `orientation` to `vertical-tb`. Here's an
example:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Top-to-bottom orientation is also supported by setting `orientation` to `vertical-tb`. Here's an
example:
In a Right-to-Left (RTL) context, vertical sliders function from top to bottom instead of bottom to top. Here's an example of a vertical slider with RTL enabled:

elements: { root, range, thumb },
states: { value },
} = createSlider({
orientation: 'horizontal-rl',
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
orientation: 'horizontal-rl',
rtl: true,
orientation: "horizontal"

elements: { root, range, thumb },
states: { value },
} = createSlider({
orientation: 'vertical-tb',
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
orientation: 'vertical-tb',
rtl: true
orientation: 'vertical',

@@ -4,7 +4,7 @@ import type { Writable } from 'svelte/store';
import type { createSlider } from './create.js';
export type { SliderComponentEvents } from './events.js';

export type SliderOrientation = 'horizontal' | 'vertical';
export type SliderOrientation = 'horizontal' | 'horizontal-rl' | 'vertical' | 'vertical-tb';
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export type SliderOrientation = 'horizontal' | 'horizontal-rl' | 'vertical' | 'vertical-tb';
export type SliderOrientation = 'horizontal' | 'vertical';

Copy link
Member

@TGlide TGlide 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 so much! I left some comments 🙂

disabled: disabledAttr($disabled),
'aria-disabled': ariaDisabledAttr($disabled),
'aria-disabled': disabledAttr($disabled),
// TODO: Is aria-orientation missing here?
Copy link
Member

Choose a reason for hiding this comment

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

It is!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, about that. I did some research and apparently the aria-disabled and aria-orientation attributes should be on the thumb, not the root. That's a breaking change.

Copy link
Member

Choose a reason for hiding this comment

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

No worries, we can change these. We can keep the data-attributes on the root as well though

src/lib/builders/slider/create.ts Outdated Show resolved Hide resolved
src/lib/builders/slider/create.ts Outdated Show resolved Hide resolved
style.translate = horizontal ? '-100% 0' : '0 100%';
} else if (index !== 0) {
style.translate = horizontal ? '-50% 0' : '0 50%';
if ($orientation === 'horizontal' && $dir === 'rtl') {
Copy link
Member

Choose a reason for hiding this comment

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

These ifs can be a bit complex too, something similar to what i've shown before would be useful 😄

Copy link
Contributor Author

@abdel-17 abdel-17 Dec 16, 2023

Choose a reason for hiding this comment

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

These ifs can be a bit complex too, something similar to what i've shown before would be useful 😄

I'm not the biggest fan of ternaries, personally, but I'll fix the ifs. I wish JS had native pattern matching or switch statements with multiple values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey! So I just pushed the changes. I chose a different approach from ternary statements. If you still prefer ternaries, I have no problem refactoring the code, but I think the new changes are much more readable than both the ternaries and the if statements.

Copy link
Member

Choose a reason for hiding this comment

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

I do prefer the ternaries, but the direction derived with the switch case is pretty nice too 😄 You can keep it!

Comment on lines +140 to +142
// TODO: Consider removing `aria-disabled` from here.
// `aria-disabled` doesn't make sense on the root
// because the slider `role` is on the thumb.
Copy link
Member

Choose a reason for hiding this comment

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

Let's do it, we can keep the data attribute

@TGlide TGlide merged commit 879ac5f into melt-ui:develop Dec 17, 2023
4 checks passed
@github-actions github-actions bot mentioned this pull request Dec 17, 2023
lolcabanon pushed a commit to lolcabanon/melt-ui that referenced this pull request Dec 28, 2023
Co-authored-by: Thomas G. Lopes <26071571+TGlide@users.noreply.github.com>
@abdel-17 abdel-17 deleted the feat/slider-rtl-support branch February 14, 2024 12:21
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

Successfully merging this pull request may close these issues.

3 participants