suid icon indicating copy to clipboard operation
suid copied to clipboard

Transitions issues due to mountOnEnter/unmountOnExit

Open Hideman85 opened this issue 1 year ago • 0 comments

I'm getting a few issues with the transitions as follow:

  1. Grow: Despite unmountOnExit set the components remain in dom after exit animation
    • Expect to be destroyed
  2. Slide: Changing the property direction while in is false makes the component to show, goes from direction A to B and hide
    • Expect to keep the component hidden
  3. Slide: Multiple slide (like tabs) with the properties mountOnEnter unmountOnExit do only mount/show the first one, as soon as removed the tabs works fine

Sample code
import { Component, createSignal, For } from 'solid-js';

import { Pagination, PaginationItem, Slide, Stack, styled } from '@suid/material';


const StyledPagination = styled(Pagination)(() => ({
  display: 'flex',
  justifyContent: 'center',
  '> ul': {
    gap: '1rem',
    '> li > button': {
      padding: '0.5rem 2rem',
      fontSize: '1.5rem',
      height: 'auto',
    },
  },
}));

const General: Component = () => (
  <h1 style={{background: 'red'}}>General</h1>
)

const Graphics: Component = () => (
  <h1 style={{background: 'blue'}}>Graphics</h1>
)

const Controls: Component = () => (
  <h1 style={{background: 'green'}}>Controls</h1>
)

const Tab: Component<{ shown: boolean, dir: 'left' | 'right', component: Component }> = (props) => {
  const shown = () => props.shown;
  const dir = () => props.dir;
  const Component = props.component;

  return (
    <>
      <p>Component {Component.name} shown {`${shown()}`} dir {dir()}</p>
      <Slide in={shown()} direction={dir()} mountOnEnter unmountOnExit timeout={{ appear: 1000, enter: 1000, exit: 1000 }}>
        <Component />
      </Slide>
    </>
  )
};

const tabs = [
  { name: 'General', component: General, },
  { name: 'Graphics', component: Graphics, },
  { name: 'Controls', component: Controls, },
];

const GameOptions: Component = () => {
  const [prevTab, setPrevTab] = createSignal(-1);
  const [nextTab, setNextTab] = createSignal(0);

  const setTab = (tab: number) => {
    setNextTab((curr) => {
      if (curr == tab) return curr; // Do nothing if same
      setPrevTab(curr);
      return tab
    })
  }
  const dir = (tab: number) => {
    if (nextTab() > prevTab()) {
      return tab >= nextTab() ? 'left' : 'right';
    }
    return tab > nextTab() ? 'left' : 'right';
  }

  return (
    <Stack gap='1.5rem'>
      <StyledPagination
        page={nextTab() + 1}
        onChange={(_, num) => setTab(num - 1)}
        count={tabs.length}
        siblingCount={tabs.length - 2}
        shape='rounded'
        size='large'
        renderItem={(item) => <PaginationItem {...item} page={tabs[item.page - 1].name} />}
      />
      <Stack flex={1}>
        <p>Prev tab {prevTab()}, next tab {nextTab()}</p>
        <For each={tabs}>
          {(tab, idx) => <Tab shown={idx() == nextTab()} dir={dir(idx())} component={tab.component} />}
        </For>
      </Stack>
    </Stack>
  );
}

Thanks in advance for your help

Hideman85 avatar Nov 18 '24 12:11 Hideman85