microsoft / fluentui

Fluent UI web represents a collection of utilities, React components, and web components for building web applications.
https://react.fluentui.dev
Other
18.31k stars 2.71k forks source link

[Bug]: Drawer does not animate in when `open=true` on first render #30452

Closed Weffe closed 7 months ago

Weffe commented 7 months ago

Library

React Components / v9 (@fluentui/react-components)

System Info

System:
    OS: Windows 11 10.0.22621
    CPU: (8) x64 Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
    Memory: 10.00 GB / 31.60 GB
  Browsers:
    Chrome: 121.0.6167.87
    Edge: Chromium (121.0.2277.83)
    Internet Explorer: 11.0.22621.1

Are you reporting Accessibility issue?

None

Reproduction

https://codesandbox.io/p/sandbox/serene-montalcini-wzgtly?file=%2Fsrc%2FApp.tsx%3A12%2C28

Bug Description

Actual Behavior

During the first render, if open=true, the Drawer is immediately painted with no animation in.

Expected Behavior

During the first render, if open=true, then we should animate in the Drawer instead of it abruptly appearing.

Logs

No response

Requested priority

Normal

Products/sites affected

No response

Are you willing to submit a PR to fix?

no

Validations

ValentinaKozlova commented 7 months ago

Hello @Weffe, I got an error "Sandbox not found". Could you please provide a working link for reproduction?

image

Narvalex commented 7 months ago

I actually like the "feature" of not animating on first render, though. I feels cleaner for me to only animate on user intereaction, and not on first render. Thoughts?

Weffe commented 7 months ago

Hello @Weffe, I got an error "Sandbox not found". Could you please provide a working link for reproduction?

image

Sorry, I forgot to make the link public. Updated so you should be able to visit it now:

https://codesandbox.io/p/sandbox/serene-montalcini-wzgtly?file=%2Fsrc%2FApp.tsx

Weffe commented 7 months ago

I actually like the "feature" of not animating on first render, though. I feels cleaner for me to only animate on user intereaction, and not on first render. Thoughts?

We've got some custom hooks that let's us write imperative looking ui rendering code such that it looks like this:

type ResolveWith = () => boolean;
type CreateContentFn = (resolveWith: ResolveWith) => React.ReactElement;
type RenderHelperFn = (createContent: CreateContentFn): Promise<boolean>;

function useRender() {
  return function render(createContent: CreateContentFn): Promise<boolean> {
    return new Promise((resolve) => {
      createContent(resolve);
    })
  } 
}

There's some more magic with the rendering container/cleanup, etc. happening in useRender but I've omitted it for brevity.


// MyComponent.tsx

async function onDeleteProduct(product, user, api, render: RenderHelperFn) {
    if (user.permission === 'owner') {
        const shouldDelete = await render((resolveWith) => {
            return (
                <Drawer open={true}>
                    Are you sure you want to delete this product?
                    <Button onClick={() => resolveWith(true)}>Yes</Button>
                    <Button onClick={() => resolveWith(false)}>No</Button>
                </Drawer>
            );
        });

        if (shouldDelete) {
            api.deleteProduct(product.id);
        }
    }
}

function MyComponent({ products, user, api }) {
    const render = useRender();

    return products.map((product) => (
        <Button onClick={() => onDeleteProduct(product, user, api, render)}>Delete {product.name}</Button>
    ));
}

So in our case, the Drawer is rendered immediately with open=true but it doesn't animate in. The workaround is to render the drawer with open=false and then change it to open=true on the next tick to get the animation working. I see in useMotion() there's a config object animate on first render that could be used to address this bug (if it's appropriate).

Our case is a bit unique but there's possibly other times where a dev might want to render an open drawer immediately but still have it animate in.

ValentinaKozlova commented 7 months ago

@Weffe, it is expected behavior that Drawer does not animate on first render. cc: @marcosmoura

Weffe commented 7 months ago

Okay, thank you for the clarification.