Comments (10)
Super glad to see this. I already started scouring react / vue code.
How to you prefer implement 'wait' mechanism for end of transition ? Basing of events or like in react repo with setTimeout
- they already left comment that it can be improved. I was wondering about general idea...
from ember-headlessui.
This is a work-in-progress and I'm not ready to make a PR yet, but I took the general idea of the React/Vue implementation and adapted it for use with Ember
The idea is the same; read the transition duration and delay and resolve a promise after that much time has passed. They have a lot of stuff in the React implementation, at least (since that's what I have been using as my frame of reference; I'm better at reading React code that Vue code) around disposables that are not relevant for the Ember implementation, as Ember Concurrency tasks will be used to handle all the asynchrony and they will handle cancellation for us out-of-the-box.
This utility got it's own tests, so I feel pretty confident that it works correctly
from ember-headlessui.
What's tricky for me right now, which I'm working out how I want to approach, is the difference between the @show
argument and some internal concept of "the component should be mounted right now". It's not exactly 1:1 -- if you transition from false
to true
then the component should become mounted. If you transition from true
to false
, though, you should actually do the following:
- Apply the
leave-from
classes - Wait for the transition duration
- Apply the
leave-to
classes - Then actually unmount the component
So there's a whole process that needs to happen as a side-effect of a property changing, which is not really something that Ember has a great API around these days. We can use the did-update
modifier but it's kind of awkward in this case. We also run into a problem when using did-update
, where you don't have an element to bind the did-update
modifier to when the component is unmounted, because there's nothing being rendered!
A Resource is probably the right abstraction here, but that would require another external dependency on ember-could-get-used-to-this
. I know @achambers would prefer we avoid dependencies, and I am not a fan of depending on a package like that which is speculating on the API that may or may not someday become mainstream. (P.S. Please don't take that as a shot at you @achambers -- avoiding dependencies is a good practice to follow and I agree we should try to adhere to it! It's unfortunate that the Observer API is no longer recommended without a good replacement being part of the public API).
I'm currently iterating on different concepts of what might work here, since there's some subtlety around getting the sequence of events correct!
from ember-headlessui.
1. Apply the `leave-from` classes 2. Wait for the transition duration 3. Apply the `leave-to` classes 4. _Then_ actually unmount the component
Are you sure that is correct ? I was thinking rather:
- apply leave and leave-from
- apply leave-to, remove leave-from
- now wait for transition duration
- unmount component
Am I missing something ? 🤔
from ember-headlessui.
I might have written it out wrong here, but I think the implementation is correct
This Ember Concurrency task here
maps to the React utility function here
And I call it with the appropriate sets of classes based whether we're transition to/from being shown
from ember-headlessui.
Oh, this discussion excites me. Thanks for taking this on @alexlafroscia .
Don't worry Alex, not shots fired here ;) It's just a general preference I think it'd be useful to have in this repo but it's by no means cut and dry and we should be pragmatic about each situation. I have full confidence that if you think there is a a good reason to introduce something then it's the right thing to do.
ember-could-get-used-to-this
certainly is a funny one where that's concerned though I suppose due to it's experimental nature.
One question that came to mind when reading through this thread is - is there any inspiration we can take from https://github.com/peec/ember-css-transitions around how we do some of this stuff?
from ember-headlessui.
That's interesting @achambers! I've never seen that repo before; it looks really similar to the nature of the Transition
component!
I have Transition
like... 60% implemented at this point on my branch. All of the tests are passing for the Transition
component itself; I just need to push through the Transition::Child
tests as well, but I think that should be pretty easy.
For now, the implementation depends on a Resource
from ember-could-get-used-to-this
; I needed some way to "listen" for updated to this.args.show
without using the did-update
modifier (since we always need to respond to changes to the property but the DOM node rendered by Transition
is not always actually mounted). The usage looks like this
The resource itself then manages the little state machine to get the component mounting correct
The logic is basically
- If
this.args.show
is transitioningfalse -> true
- Immediately mount the component
- If
this.args.show
is transitioningtrue -> false
- Wait for the transition duration/delay to pass
- Then un-mount the component
from ember-headlessui.
Whew! After a morning of refactoring, I was able to remove the dependency on ember-could-get-used-to-this
. We still depend on tracked-maps-and-sets
, but it's small, tree-shakeable and intended to be a low-level primitive. I'm feeling better about my approach now that I don't need to introduce that dependency!
The key was to turn each Resource
into a Helper
instead, which is called using invokeHelper
. This is all public API as of Ember 3.25, which is the minimum version for this addon anyway
from ember-headlessui.
That's huge! Actually, I was concern about the fact that we use the concept of '@resource' for that. I felt that main intention of it was rather loading data ? (Correct me if I am wrong). Invoke helper
it is more primitive and seems like a more adequate solution in our case, so well done. Can't wait to see it in action
from ember-headlessui.
I felt that main intention of it was rather loading data ?
My take is that, rather than the intention being “data loading”, it’s more about things that produce a value with a distinct lifecycle. Data loading is a specific example of that; there are some inputs that might change, a request to perform that introduces a loading state, error handling, success handling… Resources can be a way to model that.
The class string for the Transition
component is also a value with a distinct lifecycle, though; we need to apply certain classes when entering, then change them after a timeout. Same with leaving; different classes, but also dependent on component state and time. From this perspective, I don’t know that a Resource is the wrong abstraction, but the reality is that we can also use a Helper to do this (even if it’s more awkward) and I don’t like the idea of committing to use of an API that hasn’t really solidified yet.
from ember-headlessui.
Related Issues (20)
- Error in Embroider enabled apps using `@tagName` with `<Menu>` HOT 4
- Document Testing Best-Practices
- Some tests fail after upgrading `ember-auto-import` HOT 6
- Not compatible with ember 4 HOT 1
- Closing issue when using powerselect inside a dialog HOT 3
- Docs for using Tailwind HOT 4
- Implement Disclosure component HOT 7
- Bump `@embroider/macros` HOT 5
- Feedback welcome
- Transitions are throwing errors in Fastboot
- Move menu focus trap to containing element
- Implement <ComboBox> component HOT 2
- Build is broken due to external dependency hell HOT 10
- release config broken: Could not infer "repo" from the "package.json" file. HOT 2
- Click on `dialog.Overlay` does not close the modal HOT 1
- TypeError: can't convert value to string
- BUG: click outside <Dialog /> should be allowed HOT 6
- `<Transition>` with `<Dialog>` breaks clicking the overlay to close HOT 3
- Update `Transition` component to allow to be renderless HOT 4
- The active `Listbox` option doesn't scroll into view when using keyboard arrows
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ember-headlessui.