modify settings Category component styles and functionality to be animated by default

pull/67/head
dperolio 3 years ago
parent 64d7862397
commit 76ab552aaf
No known key found for this signature in database
GPG Key ID: 3E9BBAA710D3DDCE

@ -1,23 +1,45 @@
import React, { memo, useState, isValidElement } from 'react';
import React, { memo, useState, isValidElement, useRef } from 'react';
import { joinClassNames } from '@vizality/util/dom';
import { isComponent } from '@vizality/util/react';
import { getModule } from '@vizality/webpack';
import { useMeasure, useToggle } from '@vizality/hooks';
import { motion } from 'framer-motion';
import { Icon } from '..';
export default memo(({ title, description, icon, children, opened, className }) => {
const [ isOpened, onChange ] = useState(opened === undefined ? opened : false);
/**
* @component
* Some parts sourced from @see {@link https://codesandbox.io/s/animate-height-framer-motion-yn59l?file=/src/AnimateHeight.js}
*/
export default memo(({ title, description, icon, children, opened, className, ...other }) => {
const [ collapsed, toggleCollapsed ] = useToggle(opened === undefined ? !opened : true);
const { container, icon: _icon, description: _description, label } = getModule('icon', 'container', 'description');
const { size12, size16 } = getModule('size10', 'size12', 'size16');
const ref = useRef(null);
const bounds = useMeasure(ref);
/**
* Get the duration of the animation depending upon the height provided.
* @param {number} height of container
*/
const getAutoHeightDuration = height => {
if (!height) {
return 0;
}
const constant = height / 36;
return Math.round((4 + 15 * constant ** 0.25 + constant / 5) * 10);
};
return (
<div
className={joinClassNames('vz-settings-item', 'vz-settings-category', className, container)}
vz-opened={isOpened ? '' : null}
vz-expanded={!collapsed && ''}
vz-collapsed={collapsed && ''}
{...other}
>
<div
className='vz-settings-category-title-wrapper'
onClick={() => onChange(!isOpened)}
onClick={toggleCollapsed}
tabindex='0'
>
{(isComponent(icon) || isValidElement(icon)) && icon}
@ -43,11 +65,33 @@ export default memo(({ title, description, icon, children, opened, className })
size='18'
/>
</div>
{isOpened &&
<div className='vz-settings-category-inner'>
<motion.div
className='vz-settings-category-inner'
initial={!collapsed ? 'open' : 'collapsed'}
animate={!collapsed ? 'open' : 'collapsed'}
inherit={false}
variants={{
open: { height: 'auto' },
collapsed: { height: 0 }
}}
transition={{
duration: getAutoHeightDuration(bounds.height) / 2000
}}
>
<div ref={ref} className='vz-settings-category-contents'>
{children}
</div>
}
{/* {typeof children === 'function'
? (
children(ref)
)
: (
<div ref={ref} className='vz-settings-category-contents'>
{children}
</div>
)
} */}
</motion.div>
</div>
);
});

@ -2,15 +2,18 @@
.vz-settings-category {
$base: &;
margin-bottom: 30px;
margin-bottom: 16px;
padding: 0;
border-radius: 8px;
flex-direction: column;
&:hover {
background-color: var(--background-secondary);
}
& + & {
margin-bottom: 10px;
/**
* Targetting any elements after a category that aren't another category.
*/
& + *:not(.vz-settings-category) {
margin-top: 60px;
}
&-meta {
flex: 1;
@ -34,22 +37,22 @@
&-title-icon-wrapper {
transition: transform 0.2s;
}
&[vz-opened] {
#{$base}-icon-wrapper {
background: var(--background-floating);
}
&[vz-expanded] {
#{$base}-title-wrapper {
background: var(--background-tertiary);
background: var(--background-secondary-alt);
color: var(--interactive-hover);
}
#{$base}-title-icon-wrapper {
transform: rotate3d(0, 0, 1, 90deg);
}
}
&-contents {
padding: 20px;
}
&-inner {
padding: 30px 20px;
width: 100%;
box-sizing: border-box;
overflow: hidden;
> div:last-of-type {
margin-bottom: 0;
.divider-3573oO {

Loading…
Cancel
Save