-
-
Notifications
You must be signed in to change notification settings - Fork 298
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
feat/dynamic-transitions #1533
feat/dynamic-transitions #1533
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
@endigo9740 Some Notes and clarifications about the changes
Thank you for taking the time to check this. |
Looking good so far, to respond to your questions:
Also thanks for follow our pattern of implementing a |
no not really, I just thought we wanted them to still be reactive. I will go ahead and follow your tips for now and commit first when I get more info about the types. after that should I wait for another review or just implement the rest of the components? |
@ryceg is based near Australia so he'll be on in a few hours - let's wait for his feedback and then I'd like to do one more full audit with all changes in place. Once that's settled we can move forward with other components. We won't have this in time for tomorrow's release so take your time, no rush. We'll have a couple weeks to get this ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome stuff! Just a couple typing fixes, plus the @deprecated
syntax
EDIT: Oh, plus you might need to import slide
packages/skeleton/src/lib/components/Accordion/AccordionItem.svelte
Outdated
Show resolved
Hide resolved
packages/skeleton/src/lib/components/Accordion/Accordion.svelte
Outdated
Show resolved
Hide resolved
packages/skeleton/src/lib/components/Accordion/Accordion.svelte
Outdated
Show resolved
Hide resolved
packages/skeleton/src/lib/components/Accordion/AccordionItem.svelte
Outdated
Show resolved
Hide resolved
packages/skeleton/src/lib/components/Accordion/AccordionItem.svelte
Outdated
Show resolved
Hide resolved
packages/skeleton/src/lib/components/Accordion/Accordion.svelte
Outdated
Show resolved
Hide resolved
Thanks @ryceg! |
…eat/dynamic-animations
@ryceg Thank you very much, this looks awesome! |
@endigo9740 I have implemented the fixes mentioned by @ryceg . |
packages/skeleton/src/lib/index.ts
Outdated
@@ -14,6 +15,11 @@ export type { PopupSettings } from './utilities/Popup/types'; | |||
// This type alias is to identify CSS classes within component props, which enables Tailwind IntelliSense | |||
export type CssClasses = string; | |||
|
|||
export interface TransitionSettings { | |||
transition: (...args: Parameters<typeof slide>) => TransitionConfig; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ryceg I like that @Mahmoud-zino has created a global shared type for reuse, but I'v noted we're using slide
here as the default. Is there a more generic value we can use here? I believe transitions are just functions by default - do we provide a generic function here?
This may tie into another issue I'll raise in the PR thread in regards to removing animations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@endigo9740 yeah I looked into it, this will work with most transitions but not draw
or crossfade
because they take different parameters. I think the only way to make it really generic is by using any
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use a union type;
transition: (...args: Parameters<typeof blur | fade | fly | slide | scale>) => TransitionConfig
It's not pretty, and it doesn't support custom transitions that include additional params (although you could slap a | Record<string | any>
on the end to accommodate that) but it does work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@endigo9740 @ryceg Is using object
a bad idea? I achieved the same functionality by changing the params to object and it works.
export interface TransitionSettings {
transition: (node: HTMLElement, params: object) => TransitionConfig;
params: object;
}
and like this, we are not dependent on slide
anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typescript works by narrowing wider types; the object
type simply tells Typescript that it's not one of the other primitives. Both are technically "correct", but you're going to be more accurate with a union type (accuracy in the sense of trying to make your types resemble the corresponding data).
Try it out- with the union type you'll get intellisense on the object, and it'll narrow down the possible choices as you add props that don't exist on some of the interfaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Mahmoud-zino I'm not sure another prop would help since the transition directives are still applied to the elements. We need to alter the value passed to the transition:in
and transition:out
, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes and no, we can do something like this repl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I like it, but there's a lot of boilerplate. We definitely don't want that to live within every component. It would need to be abstracted for reuse by all components.
I'm was thinking something more like how we handle dynamic actions:
https://github.com/skeletonlabs/skeleton/blob/dev/packages/skeleton/src/lib/components/Avatar/Avatar.svelte#L20
If the action is not present, we still need to pass something to use:
directive, so we pass an empty function:
https://github.com/skeletonlabs/skeleton/blob/dev/packages/skeleton/src/lib/components/Avatar/Avatar.svelte#L59
In practice that would look something like this:
<SomeComponent
transitionIn={{transition: () => {}, params: {}}}
transitionOut={{transition: () => {}, params: {}}}
/>
I don't like this though, we're then forcing end users to pass a bunch of extra noise.
This makes me wonder if we build in and include our own custom transition called disabled
:
function disabled(node, { duration }) {
return { duration: 0, css: t => `` };
}
Then allow users to provide this like so:
<SomeComponent
transitionIn={{transition: disabled, params: {}}}
transitionOut={{transition: disabled, params: {}}}
/>
Then if we can make params optional, it could be:
<SomeComponent
transitionIn={{transition: disabled}}
transitionOut={{transition: disabled}}
/>
But this requires importing disabled
to use it and I'm not sure this guarantees there won't be a performance hit, even if it's minor.
Really stumped on this one, it's a tough one to figure out. The limitation here is that Svelte doesn't seem to support dynamic transitions well - so in some ways it's an upstream issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@endigo9740
I like the disabled Idea, but we don't have to return anything from it. Svelte only cares about the function parameters having the correct type.
I don't know how yet but I will try to benchmark both approaches and check the performance.
This might take some time, but I will report back when I have something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a huge fan of disabled
being a function- traditionally disabled
is a boolean, and there's less friction if we don't require them to import the disabled
function just to pass it in. We could always add in a disabled
flag in an extended interface very easily, and this would also afford the ability to toggle it.
Additionally @Mahmoud-zino @ryceg we should make considerations for accessibility here - which includes the ability for users to reduce or disable animations. Should we allow a a I faintly recall that either the transition directive -or- the transitions themselves are built to support prefers-reduced-motion. Perhaps this is already handled for us as long as users use the canned transitions. But what if they don't - what if a custom transition is used that isn't built to support this? Reference: I'll need to do a bit more reading on this subject, but wanted to encourage others to join in. EDIT From the post above
This means we can probably rely on Svelte's canned transitions to adhere to |
So under the hood, the transitions apply CSS as export let transitionIn: TransitionSettings = { transition: slide, params: { duration: $prefersReducedMotion ? 0 : 200 } }; Thus, no tweening occurs between This allows people to still customize the transition behaviour to account for the media query manually, but protects end-users if they just go with the default. |
@Mahmoud-zino @ryceg I commented on the type thread above. I do like the suggestion of the import { writable, type Writable } from 'svelte/store';
export const prefersReducedMotion: Writable<boolean> = writable(false); As discussed previously, we'll need a new "Animations" or "Transitions" page in Docs > Essentials > Transitions (or Animations) that covers the process of modifying transitions. This store can be covered there. I'm happy to introduce this once we've finalized on the type issue above. So type, doc, and then I think we're good to move forward with other components. Given how quickly things are changing lately I might suggest further component updates come as their own dedicated PRs |
export type DefaultTransitionParams = Parameters<typeof blur | typeof fade | typeof fly | typeof slide | typeof scale>[1] &
AdditionalTransitionProps;
export type TransitionParams = (DefaultTransitionParams | Record<string, any>) & AdditionalTransitionProps;
interface AdditionalTransitionProps {
/** Disable the transition completely. */
disabled?: boolean;
/**
* By default, animations will be disabled if the media query `prefers-reduced-motion` is present.
* There are many reasons why you might want to override this behavior, such as for minor animations.
*/
ignoreReducedMotion?: boolean;
}
export interface TransitionSettings {
transition: (node: Element, params?: TransitionParams) => TransitionConfig;
params?: TransitionParams;
} This is an opinionated way of doing it, opting for people having to explicitly set to ignore reducedMotion- this would be my preference, as accessibility should be the default, and people should opt in to patterns that may reduce accessibility. The |
Svelte has I like the idea of extending the interface to take disabled and ignoreReducedMotion. I will implement these changes and wait for you to take a look at them in the code. Thanks |
🦋 Changeset detectedLatest commit: 6df83bf The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
@Mahmoud-zino I've done a follow up per the items mentioned in my prior review:
Gotcha, we can leave that for now then.
Thanks for adjusting this - looks good.
Looks great, I just committed a few tweaks and adjustments to the text and provided a more detailed example snippet. But overall it does what it needs to do. Great job. Additional Items
If you want to take a stab at converting this the custom Crossfade transition to a proper reusable JS transition per the Svelte Docs you can @Mahmoud-zino, but otherwise I think we set it aside and revisit custom transitions in a dedicated pass in the future. Here's the docs if you want to reference how that works: If you can update the Toast transition I think this PR is officially ready for the v2 release! |
I agree |
Linked Issue
Closes #1322
Closes #1694
Description
Changsets
feat: Implemented dynamic transitions to the Accordion component.
Checklist
Please read and apply all contribution requirements.
dev
branch (NEVERmaster
)docs/
,feat/
,chore/
,bugfix/
pnpm format
pnpm test