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

v2 #908

Open
zernonia opened this issue May 11, 2024 · 14 comments · May be fixed by #1326
Open

v2 #908

zernonia opened this issue May 11, 2024 · 14 comments · May be fixed by #1326

Comments

@zernonia
Copy link
Member

zernonia commented May 11, 2024

Announcement: Changes Coming to Radix Vue

Introduction

First and foremost, we really want to express appreciation for all the effort put in by the Radix UI team in creating the absolutely powerful, unstyled, high-quality, and accessible components that this project was originally ported from.

Background

However, as feature requests grew, Radix Vue began to add more components and features, and modify certain behaviors specifically tailored for Vue. As a result, Radix Vue started to feel like a unique component library rather than just the ported version of Radix UI. Therefore, we are planning to give it a different identity.

What's Coming in v2?

Note

  1. We will still be pushing bug fixes and introducing some new primitive components prior to the v2 release.
  2. We are still brainstorming the new identity name. Please share any ideas you have in the comments below.
  3. We are open to suggestions for areas of improvement. Please ensure that any suggestions are sensible and would result in a general improvement rather than addressing only a specific edge-case.

Important

We understand that these changes may require some major adjustments in your project, and we apologize for any inconvenience in advance.

@zernonia zernonia pinned this issue May 11, 2024
@k11q
Copy link
Member

k11q commented May 18, 2024

Hi @zernonia ! Big decision! I had my concerns but after several thought and looking back at the project, I think a rebrand is a really good idea! I think what you and other contributors have been building and currently building has turned this library into a very big project, and in many sense it has grown larger than the radix primitives. I think a rebrand is sign of growth and by detaching from the previous radix brand, it removes a significant blocker, allowing decisions to be made without the concern of fitting the radix brand. Overall i'm very excited for the future of the library and see what you'll come up with 🚀🚀🚀

@gustojs
Copy link

gustojs commented May 19, 2024

How about something that works both ways? Can be regarded as something separate, but still points at the origins. Vuedix, for example.

Similarily to how Nuxt and Next exist as separate entities that both influence each other.

@edtorba
Copy link
Contributor

edtorba commented May 22, 2024

Just a hint, you can also look into Latin words, at least it seems that's what the Radix team did, e.g., radix = root (it seems). What you want is something simple and catchy, while also being unique.

@Rolanddoda
Copy link

@zernonia does this means that there are going to be breaking changes in v2?
I think there might be a lot of people evaluating Radix Vue and if 1.x is going to be stale after a few months, then that should be made clear.

@cyyynthia
Copy link
Contributor

While the project doesn't follow semver, a major version bump is always indicative of some breaking changes. I don't think the project has a clear list of what's going to break, but form-related components are planned to go through changes such as #1017, internal changes that may affect their behavior (backing hidden field, exposed API, ...)

Radix Vue published breaking changes for components in alpha in patch-releases, and these patch-releases often contain features.

As someone who recently adopted Radix Vue, I can say for those looking to adopt it it's very promising and we're having great results in the project it's being used in, but don't underestimate the alpha label on components (see prev. remark on breaking changes), and remember that the project is quite young so there are a handful of areas where it can improve 😅

I don't think v2 will bring huge breaking changes, but I'm not a maintainer of the project and haven't been in its internals for long enough to know what needs to change. So long your project follows a healthy component structure (you generally shouldn't use raw components and wrap them with your own styles first; or use something like shadcn-vue which is versioned separately) the changes shouldn't be too bad - but, I'm not a maintainer just a user who really enjoyed using this lib thus far 😃

Possibly relevant issues tagged https://github.com/radix-vue/radix-vue/labels/v2:

@zernonia
Copy link
Member Author

@Rolanddoda Yes in the description we mention that v2 will have breaking changes (major adjustments in your project). Worry not that we will mentioned all of that breaking changes in the changelog, and will be releasing rc's earlier too.

@cyyynthia Currently we try our best to follow semver 😁, especially for the breaking changes part. In minor version we have new changes but with deprecation warning, unless for alpha component. But we try to minimize the breaking in alpha as well and aimed to publish major changes in the same minor version.

@teleskop150750
Copy link
Contributor

teleskop150750 commented Sep 13, 2024

What I would like to see in Radix-vue and what I am trying to implement in my fork perigee-ui

  1. I use let variables or useRef where React uses useRef. Radix-vue creates unnecessary reactive ref variables in all places, which is completely unnecessary.

  2. I use the composeEventHandlers hook. This hook allows canceling events through preventDefault. Unfortunately, in Vue, handlers received from the parent component end up at the end of the array and are called last (I might have misunderstood the code, there may be inaccuracies).

  3. I use attribute inheritance instead of redefining them in each component, generating unnecessary code. Moreover, it seems that Volar now has typing for attrs. This approach may change if it turns out to be inconvenient to use.

  4. I do not use their useForwardExpose. A hook that replaces the original expose object to pass props outside. Why, if access to them is already available.

  5. I do not use asChild for implementing primitives. Instead, I wrap the component's content in a hook and use it. I thought it was a bit cumbersome to use so many empty wrapper components when they can be eliminated. For example, the FocusScope wrapper is 3 components: FocusScope -> Primitive -> Slot. If there are 3 such wrappers, it is already a tree of 9+ components.
    This is currently a test implementation.

  6. I think it's unlikely. In the distant future, there is a thought to abandon components and leave only hooks that return props. For example, like in Zag and Melt. If the Vapor mod comes out in our lifetime, this method will allow us to get rid of Primitive and Slot

  7. Different implementation of Collection without Map, VDom. Radix vue

  8. Presence is just a hook for me. The same approach was found in Solid's Kobalte. In radix-vue, it is the reason for the absence of content on the first render in components like Accordion.

  9. Availability of component context export for access in user code. It seems that this was promised to be added in Radix v2. I am not following.

  10. No empty wrappers that do nothing.

  11. An easier way to get the current element without computed. Radix-vue

  12. Scoped Context WIP Link Link

@yacinehmito
Copy link

@teleskop150750 Why are you outlining the differences between your library and this one in the present issue? I don't see anyone asking the question here. It feels inappropriate.

@teleskop150750
Copy link
Contributor

teleskop150750 commented Sep 13, 2024

@yacinehmito I described what I wanted to see in radix 2. Where is it better to write to discuss?

@zernonia
Copy link
Member Author

Thanks for sharing your thoughts @teleskop150750 .

While I appreciate the efforts to streamline internal structures, I believe that most of these suggestions mainly target internal component architecture rather than offering tangible benefits to the end-user. The primary goal of v2 is on features that require breaking changes and is designed to bring tangible improvements for the end user.

Some of your ideas could be valuable for long-term architectural improvements, but prioritizing internal changes without direct developer-facing advantages seems like a waste of effort.

With that said, looking forward to seeing any benchmarks where these changes benefit users directly tho 😉 Feel free to post them on discussion page

@sadeghbarati
Copy link
Collaborator

@teleskop150750 Hi 👋

Each of the list items you described can be a PR and tested with pkg.pr.new capability,
You are free to research creating your own lib for your use cases.

But contributing/improving one project that is used by thousands of people is way better imo

@teleskop150750
Copy link
Contributor

teleskop150750 commented Sep 25, 2024

But contributing/improving one project that is used by thousands of people is way better imo

The first such project was OkuUI. I have already promised its author to help complete it and implement some of the listed ideas. It is a pity that Radix Vue did not want to cooperate and join forces and made its own version of the library

Moreover, Zernonia stated that such changes are currently of no interest to him.

@zernonia zernonia linked a pull request Oct 1, 2024 that will close this issue
@iamandrewluca
Copy link

@zernonia, in the issue description, the link to the project seems to be incorrect

https://github.com/orgs/unovue/projects/3

@MickL MickL mentioned this issue Oct 20, 2024
7 tasks
@mary-ext
Copy link

mary-ext commented Oct 24, 2024

thoughts on exposing components like FocusScope, FocusGuards, and DismissableLayer as public API?

I get that Radix (React) has them as internal APIs as well but we're currently having problems at work adapting Dialog due to their clunky design, so at the very least we want to have some consistency with other Radix components we are using.

right now we're considering just patching Radix Vue here but it'd be brittle because the library is bundled and mangled, which would mean we'd have to redo the patch every time we want to upgrade Radix Vue.


To summarize my issue with the Dialog component, they aren't exactly great because the "intended" way of writing them would be like so:

<DialogRoot>
  <DialogTrigger>
    open modal
  </DialogTrigger>

  <DialogPortal>
    <DialogContent>
      <HelloWorldDialog />
    </DialogContent>
  </DialogPortal>
</DialogRoot>

This is the "intended" way for dialog states to only be inited on mount and thrown away on unmount.

If this was React, I would've written this like so, where I would have a file defining both <HelloWorldDialog /> and <HelloWorldInnerDialog />

export const HelloWorldDialog = (props) => {
  return (
    <Dialog.Root>
      <Dialog.Trigger asChild>{props.trigger}</Dialog.Trigger>

      <Dialog.Portal>
        <Dialog.Content>
          <HelloWorldInnerDialog />
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
};

const HelloWorldInnerDialog = () => {
  const [count, setCount] = useState(0);

  return <div>Hello world!</div>;
};

Unfortunately, this is not React, and we are not using JSX but rather Vue's templating language, so if we want this, we'd have to make two component files, one for the exported component and one for the actual dialog component. This is super cumbersome to use, and I'd prefer we'd avoid this even if it means we won't be able to have dialogs return focus to the trigger button on unmount (we can simply write workarounds, to be fair, our dialogs aren't always coming from a trigger button anyway)

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 a pull request may close this issue.