Skip to content

[DropdownMenu][ContextMenu][RadioGroup][ScrollArea][Slider][Tabs][ToggleGroup][Toolbar] Direction provider #1119

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

Merged
merged 4 commits into from
Apr 11, 2022

Conversation

jjenzz
Copy link
Contributor

@jjenzz jjenzz commented Jan 25, 2022

Closes #749

  • Renames react-use-direction package to react-direction and exposes DirectionProvider
  • Adds new direction chromatic stories to each component to demonstrate prop and provider works

Should I bump these as a minor?

Notes for docs

  • 🔥 New direction package with DirectionProvider to change Radix components direction at app level. This used to inherit so folks might have breaking changes.
  • 🔥 Update component docs that communicate a default value for dir attribute. It's undefined now.
  • 🔥 Move dir prop from ContextMenu.Content to Root part to match implementation

@jjenzz jjenzz marked this pull request as draft January 25, 2022 14:42
@jjenzz jjenzz marked this pull request as ready for review January 25, 2022 15:17
@jjenzz jjenzz force-pushed the direction-provider branch from dba1ae5 to d928cd6 Compare January 25, 2022 15:20
@@ -125,7 +130,6 @@ const TabsList = React.forwardRef<TabsListElement, TabsListProps>(
<Primitive.div
role="tablist"
aria-orientation={context.orientation}
dir={context.dir}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved this to Tabs.Root div instead so that right-to-left content works.

Comment on lines -439 to -446
/**
* The direction of navigation between menu items.
* @defaultValue ltr
*/
dir?: RovingFocusGroupProps['dir'];

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 realised this was accepting dir prop but RovingFocusGroup never used it because it gets it from root context instead.

@jjenzz jjenzz force-pushed the direction-provider branch from 2b47484 to 773a005 Compare January 27, 2022 15:33
@jjenzz jjenzz changed the title [Menu][RadioGroup][ScrollArea][Slider][Tabs][ToggleGroup][Toolbar] Direction provider [DropdownMenu][ContextMenu][RadioGroup][ScrollArea][Slider][Tabs][ToggleGroup][Toolbar] Direction provider Jan 27, 2022
@benoitgrelard
Copy link
Contributor

Looking at chromatic, it looks like the scrollarea one is broken in the inherited scenario?

@jjenzz
Copy link
Contributor Author

jjenzz commented Jan 28, 2022

Looking at chromatic, it looks like the scrollarea one is broken in the inherited scenario?

I thought that too but it's not, it's because the direction is added to the scrollarea div now from context (which is fixed width) instead of being added to a 100% width div that wraps it.

We inherit from context now instead of from a parent element. The important part is that the vertical scroll is on left and thumb starts from right in horizontal bar.

@jjenzz jjenzz requested a review from benoitgrelard January 28, 2022 15:45
Copy link
Contributor

@benoitgrelard benoitgrelard left a comment

Choose a reason for hiding this comment

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

It seems a bit all over in terms of conventions with regards to the dir prop's default value.

It looks like you intentionally removed the default value in destructuring in places, but then sometimes a default is added inline after the useDirection() hook, sometimes not, and other times a default is added inline for specific use-cases.

There's probably a reason behind all that, but after reading this I'm wondering why we can't always default to ltr in destructuring, thus insuring there will always be a value no matter what and the convention is the same everywhere.

As to the versioning I'm still unclear what we should do here, probably ok for now to go with patches…

@benoitgrelard benoitgrelard added PR: Breaking Change This PR contains a breaking change PR: Documentation Needed This PR warrants a documentation update labels Apr 5, 2022
@andy-hook andy-hook marked this pull request as draft April 7, 2022 12:06
@andy-hook andy-hook force-pushed the direction-provider branch 3 times, most recently from f23bdb5 to ca8c652 Compare April 7, 2022 14:52

function useDirection(localDir?: Direction) {
const globalDir = React.useContext(DirectionContext);
return localDir || globalDir || 'ltr';
Copy link
Contributor

@andy-hook andy-hook Apr 7, 2022

Choose a reason for hiding this comment

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

I moved the fallback logic into the hook as I found it clearer to see the cascade preference.

@benoitgrelard re your last round of comments – I couldn't see any reason not to provide the default ltr value so I resolved them and went for this, let me know what you think though.

Edit – I think chromatic has just shown me the reason 😅

Copy link
Contributor

Choose a reason for hiding this comment

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

That's funny cause Jenna had done that originally which I asked about: #1119 (comment)

@benoitgrelard re your last round of comments – I couldn't see any reason not to provide the default ltr value so I resolved them and went for this, let me know what you think though.
Edit – I think chromatic has just shown me the reason 😅

Can you provide more detail about this bit, i'm not following.

Copy link
Contributor

@andy-hook andy-hook Apr 8, 2022

Choose a reason for hiding this comment

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

We checked in offline about this, the primary reason that I went back to passing an arg to the hook is for style. Because we can’t conditionally call hooks it’d be more verbose when done inline:

const contextDir = useDirection();
const direction = contextDir || dirProp || 'ltr' ;

vs



const direction = useDirection(dirProp)

The latter of which we seem to prefer on balance.

Can you provide more detail about this bit, i'm not following.

Seems that the original changes in this PR removed default values in certain places due to how some primitives get recomposed and the cascading effect of always setting a dir attribute from a default value. This is made clear by a preexisting bug in Toolbar where ToolbarToggleGroup doesn't respect dir="rtl" when added to Root, I think the changes were to remedy these issues.

We decided it would be clearer overall to provide a default in all cases and ensure we consistently pass dir values down the tree where necessary.

@andy-hook andy-hook force-pushed the direction-provider branch from ca8c652 to 70a00ff Compare April 7, 2022 17:14
@andy-hook andy-hook marked this pull request as ready for review April 8, 2022 13:02
@@ -177,6 +176,7 @@ const ToolbarToggleGroup = React.forwardRef<
return (
<ToggleGroupPrimitive.Root
data-orientation={context.orientation}
dir={context.dir}
Copy link
Contributor

@andy-hook andy-hook Apr 8, 2022

Choose a reason for hiding this comment

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

We need to pass this down to ToggleGroupPrimitive as we now consistently provide a fallback dir value. Without doing so ToolbarToggleGroup renders dir="ltr" if DirectionProvider is not used and <Toolbar.Root dir="rtl"/>, thus we pass it explicitly via context to prevent that.

@benoitgrelard benoitgrelard merged commit 2148ecb into main Apr 11, 2022
@benoitgrelard benoitgrelard deleted the direction-provider branch April 11, 2022 14:39
luisorbaiceta pushed a commit to luisorbaiceta/primitives that referenced this pull request Jul 21, 2022
…gleGroup][Toolbar] Direction provider (radix-ui#1119)

* Remove useDirection raf

* Use direction context in other comps

* Remove useDirection param

* Update `useDirection` usage

Co-authored-by: Andy Hook <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: Breaking Change This PR contains a breaking change PR: Documentation Needed This PR warrants a documentation update
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[useDirection] Eager hook is called on every state change.
3 participants