Skip to content

Commit

Permalink
fix(ui-toggle-details): fix ToggleDetails flickering
Browse files Browse the repository at this point in the history
Closes: INSTUI-4190
  • Loading branch information
joyenjoyer committed Sep 3, 2024
1 parent ba9046f commit bca2725
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 22 deletions.
81 changes: 75 additions & 6 deletions packages/ui-toggle-details/src/ToggleDetails/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,81 @@ By default, ToggleDetails content is hidden. To override, pass in the `defaultEx
---
type: example
---
<ToggleDetails
summary="Click to hide me!"
defaultExpanded
>
<Text weight="bold">I am expanded!</Text> {lorem.paragraph()}
</ToggleDetails>
const Example = () => {
const [state, setState] = useState({
expanded: true,
fluidWidth: true,
iconPosition: 'start',
size: 'small',
variant: 'default'
});

const handleChange = (field, value) => setState(prevState => ({ ...prevState, [field]: value }));
const handleToggle = () => setState(prevState => ({ ...prevState, expanded: !prevState.expanded }));

const renderOptions = () => {
const { fluidWidth, iconPosition, size, variant } = state;
const options = [
{ name: 'iconPosition', values: ['start', 'end'] },
{ name: 'size', values: ['small', 'medium', 'large'] },
{ name: 'variant', values: ['default', 'filled'] },
];

return (
<Flex alignItems="start">
{options.map(({ name, values }) => (
<Flex.Item margin="small" key={name}>
<RadioInputGroup
name={name}
description={name}
value={state[name]}
onChange={(e, value) => handleChange(name, value)}
>
{values.map(val => (
<RadioInput label={val} value={val} key={val} />
))}
</RadioInputGroup>
</Flex.Item>
))}
<Flex.Item margin="small">
<Checkbox
label="fluidWidth"
checked={fluidWidth}
onChange={() => handleChange('fluidWidth', !fluidWidth)}
/>
</Flex.Item>
</Flex>
);
};

const { expanded, iconPosition, size, variant, fluidWidth } = state;

return (
<div>
{renderOptions()}
<Button onClick={handleToggle}>
This Button {expanded ? 'Collapses' : 'Expands'}
</Button>
<br />
<br />
<ToggleDetails
summary="Click to hide me!"
expanded={expanded}
onToggle={(_, expanded) => handleChange('expanded', expanded)}
fluidWidth={fluidWidth}
iconPosition={iconPosition}
size={size}
variant={variant}
>
<Text weight="bold">
I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!
</Text>
</ToggleDetails>
</div>
);
};

render(<Example />)
```

ToggleDetails can be controlled:
Expand Down
9 changes: 4 additions & 5 deletions packages/ui-toggle-details/src/ToggleDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { testable } from '@instructure/ui-testable'
import { withStyle, jsx } from '@instructure/emotion'
import generateStyle from './styles'
import generateComponentTheme from './theme'
import type { ToggleDetailsProps, ToggleDetailsStyleProps } from './props'
import type { ToggleDetailsProps } from './props'
import { allowedProps, propTypes } from './props'
import type { ExpandableToggleProps } from '@instructure/ui-expandable'

Expand Down Expand Up @@ -75,11 +75,11 @@ class ToggleDetails extends Component<ToggleDetailsProps> {
}

componentDidMount() {
this.props.makeStyles?.({ animate: false } as ToggleDetailsStyleProps)
this.props.makeStyles?.()
}

componentDidUpdate() {
this.props.makeStyles?.({ animate: true } as ToggleDetailsStyleProps)
componentDidUpdate(_prevProps: ToggleDetailsProps) {
this.props.makeStyles?.()
}

getButtonRef = (el: Element | null) => (this._button = el as HTMLElement)
Expand Down Expand Up @@ -169,7 +169,6 @@ class ToggleDetails extends Component<ToggleDetailsProps> {
if (typeof this.props.onToggle === 'function') {
this.props.onToggle(event, expanded)
}
this.props.makeStyles?.({ animate: true })
}

render() {
Expand Down
19 changes: 8 additions & 11 deletions packages/ui-toggle-details/src/ToggleDetails/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@ const contentAnimation = keyframes`
const generateStyle = (
componentTheme: ToggleDetailsTheme,
props: ToggleDetailsProps,
state: ToggleDetailsStyleProps
_state: ToggleDetailsStyleProps
): ToggleDetailsStyle => {
const { fluidWidth, iconPosition, size, variant } = props
const { animate } = state

const positionIconAtEnd =
iconPosition === 'end' && (variant === 'filled' || fluidWidth)
Expand Down Expand Up @@ -178,15 +177,13 @@ const generateStyle = (
...fontSizeStyles[size!],
...indentDetailsStyles[size!]
},
content: animate
? {
label: 'toggleDetails__content',
opacity: 0.01,
animationName: contentAnimation,
animationFillMode: 'forwards',
animationDuration: '.3s'
}
: {}
content: {
label: 'toggleDetails__content',
opacity: 0.01,
animationName: contentAnimation,
animationFillMode: 'forwards',
animationDuration: '.3s'
}
}
}

Expand Down

0 comments on commit bca2725

Please sign in to comment.