feat: new collections (#4530)

Co-authored-by: Peng Xiao <pengxiao@outlook.com>
This commit is contained in:
3720
2023-10-27 17:06:59 +08:00
committed by GitHub
parent 9fc0152cb1
commit ef8024c657
133 changed files with 8382 additions and 3743 deletions
@@ -8,19 +8,25 @@ import {
import * as styles from './styles.css';
type DropdownButtonProps = {
size?: 'small' | 'default';
onClickDropDown?: MouseEventHandler<HTMLElement>;
} & ButtonHTMLAttributes<HTMLButtonElement>;
export const DropdownButton = forwardRef<
HTMLButtonElement,
DropdownButtonProps
>(({ onClickDropDown, children, ...props }, ref) => {
>(({ onClickDropDown, children, size = 'default', ...props }, ref) => {
const handleClickDropDown: MouseEventHandler<HTMLElement> = e => {
e.stopPropagation();
onClickDropDown?.(e);
};
return (
<button ref={ref} className={styles.dropdownBtn} {...props}>
<button
ref={ref}
data-size={size}
className={styles.dropdownBtn}
{...props}
>
<span>{children}</span>
<span className={styles.divider} />
<span className={styles.dropdownWrapper} onClick={handleClickDropDown}>
@@ -1,2 +1,2 @@
export * from './dropdown';
export * from './dropdown-button';
export * from './radio';
@@ -1,363 +0,0 @@
import { globalStyle, style } from '@vanilla-extract/css';
export const button = style({
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
userSelect: 'none',
touchAction: 'manipulation',
outline: '0',
border: '1px solid',
padding: '0 18px',
borderRadius: '8px',
fontSize: 'var(--affine-font-base)',
transition: 'all .3s',
['WebkitAppRegion' as string]: 'no-drag',
fontWeight: 600,
// changeable
height: '28px',
background: 'var(--affine-white)',
borderColor: 'var(--affine-border-color)',
color: 'var(--affine-text-primary-color)',
selectors: {
'&.text-bold': {
fontWeight: 600,
},
'&:not(.without-hover):hover': {
background: 'var(--affine-hover-color)',
},
'&.disabled': {
opacity: '.4',
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
'&.loading': {
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
'&.disabled:not(.without-hover):hover, &.loading:not(.without-hover):hover':
{
background: 'inherit',
},
'&.block': { display: 'flex', width: '100%' },
'&.circle': {
borderRadius: '50%',
},
'&.round': {
borderRadius: '14px',
},
// size
'&.large': {
height: '32px',
},
'&.round.large': {
borderRadius: '16px',
},
'&.extraLarge': {
height: '40px',
},
'&.round.extraLarge': {
borderRadius: '20px',
},
// type
'&.plain': {
color: 'var(--affine-text-primary-color)',
borderColor: 'transparent',
background: 'transparent',
},
'&.primary': {
color: 'var(--affine-pure-white)',
background: 'var(--affine-primary-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.primary:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-primary-color)',
},
'&.primary.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.primary.disabled:not(.without-hover):hover': {
background: 'var(--affine-primary-color)',
},
'&.error': {
color: 'var(--affine-pure-white)',
background: 'var(--affine-error-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.error:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-error-color)',
},
'&.error.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.error.disabled:not(.without-hover):hover': {
background: 'var(--affine-error-color)',
},
'&.warning': {
color: 'var(--affine-white)',
background: 'var(--affine-warning-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.warning:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-warning-color)',
},
'&.warning.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.warning.disabled:not(.without-hover):hover': {
background: 'var(--affine-warning-color)',
},
'&.success': {
color: 'var(--affine-pure-white)',
background: 'var(--affine-success-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.success:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-success-color)',
},
'&.success.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.success.disabled:not(.without-hover):hover': {
background: 'var(--affine-success-color)',
},
'&.processing': {
color: 'var(--affine-pure-white)',
background: 'var(--affine-processing-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.processing:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-processing-color)',
},
'&.processing.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.processing.disabled:not(.without-hover):hover': {
background: 'var(--affine-processing-color)',
},
},
});
globalStyle(`${button} > span`, {
// flex: 1,
lineHeight: 1,
padding: '0 4px',
});
export const buttonIcon = style({
flexShrink: 0,
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
color: 'var(--affine-icon-color)',
fontSize: '16px',
width: '16px',
height: '16px',
selectors: {
'&.start': {
marginRight: '4px',
},
'&.end': {
marginLeft: '4px',
},
'&.large': {
fontSize: '20px',
width: '20px',
height: '20px',
},
'&.extraLarge': {
fontSize: '20px',
width: '20px',
height: '20px',
},
'&.color-white': {
color: 'var(--affine-white)',
},
},
});
export const iconButton = style({
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
userSelect: 'none',
touchAction: 'manipulation',
outline: '0',
border: '1px solid',
borderRadius: '4px',
transition: 'all .3s',
['WebkitAppRegion' as string]: 'no-drag',
// changeable
width: '24px',
height: '24px',
fontSize: '20px',
color: 'var(--affine-text-primary-color)',
borderColor: 'var(--affine-border-color)',
selectors: {
'&.without-padding': {
margin: '-2px',
},
'&.active': {
color: 'var(--affine-primary-color)',
},
'&:not(.without-hover):hover': {
background: 'var(--affine-hover-color)',
},
'&.disabled': {
opacity: '.4',
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
'&.loading': {
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
'&.disabled:not(.without-hover):hover, &.loading:not(.without-hover):hover':
{
background: 'inherit',
},
// size
'&.large': {
width: '32px',
height: '32px',
fontSize: '24px',
},
'&.large.without-padding': {
margin: '-4px',
},
'&.small': { width: '20px', height: '20px', fontSize: '16px' },
'&.extra-small': { width: '16px', height: '16px', fontSize: '12px' },
// type
'&.plain': {
color: 'var(--affine-icon-color)',
borderColor: 'transparent',
background: 'transparent',
},
'&.plain.active': {
color: 'var(--affine-primary-color)',
},
'&.primary': {
color: 'var(--affine-white)',
background: 'var(--affine-primary-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.primary:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-primary-color)',
},
'&.primary.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.primary.disabled:not(.without-hover):hover': {
background: 'var(--affine-primary-color)',
},
'&.error': {
color: 'var(--affine-white)',
background: 'var(--affine-error-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.error:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-error-color)',
},
'&.error.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.error.disabled:not(.without-hover):hover': {
background: 'var(--affine-error-color)',
},
'&.warning': {
color: 'var(--affine-white)',
background: 'var(--affine-warning-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.warning:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-warning-color)',
},
'&.warning.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.warning.disabled:not(.without-hover):hover': {
background: 'var(--affine-warning-color)',
},
'&.success': {
color: 'var(--affine-white)',
background: 'var(--affine-success-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.success:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-success-color)',
},
'&.success.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.success.disabled:not(.without-hover):hover': {
background: 'var(--affine-success-color)',
},
'&.processing': {
color: 'var(--affine-white)',
background: 'var(--affine-processing-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.processing:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-processing-color)',
},
'&.processing.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.processing.disabled:not(.without-hover):hover': {
background: 'var(--affine-processing-color)',
},
},
});
@@ -1,4 +1,4 @@
import { style } from '@vanilla-extract/css';
import { globalStyle, style } from '@vanilla-extract/css';
export const dropdownBtn = style({
display: 'inline-flex',
@@ -9,8 +9,8 @@ export const dropdownBtn = style({
paddingRight: 0,
color: 'var(--affine-text-primary-color)',
fontWeight: 600,
background: 'var(--affine-button-gray-color)',
boxShadow: 'var(--affine-float-button-shadow)',
background: 'var(--affine-background-primary-color)',
border: '1px solid var(--affine-border-color)',
borderRadius: '8px',
fontSize: 'var(--affine-font-sm)',
// width: '100%',
@@ -22,6 +22,12 @@ export const dropdownBtn = style({
'&:hover': {
background: 'var(--affine-hover-color-filled)',
},
'&[data-size=default]': {
height: 32,
},
'&[data-size=small]': {
height: 28,
},
},
});
@@ -106,3 +112,365 @@ export const radioButtonGroup = style({
// @ts-expect-error - fix electron drag
WebkitAppRegion: 'no-drag',
});
export const button = style({
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
userSelect: 'none',
touchAction: 'manipulation',
outline: '0',
border: '1px solid',
padding: '0 18px',
borderRadius: '8px',
fontSize: 'var(--affine-font-base)',
transition: 'all .3s',
['WebkitAppRegion' as string]: 'no-drag',
fontWeight: 600,
// changeable
height: '28px',
background: 'var(--affine-white)',
borderColor: 'var(--affine-border-color)',
color: 'var(--affine-text-primary-color)',
selectors: {
'&.text-bold': {
fontWeight: 600,
},
'&:not(.without-hover):hover': {
background: 'var(--affine-hover-color)',
},
'&.disabled': {
opacity: '.4',
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
'&.loading': {
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
'&.disabled:not(.without-hover):hover, &.loading:not(.without-hover):hover':
{
background: 'inherit',
},
'&.block': { display: 'flex', width: '100%' },
'&.circle': {
borderRadius: '50%',
},
'&.round': {
borderRadius: '14px',
},
// size
'&.large': {
height: '32px',
},
'&.round.large': {
borderRadius: '16px',
},
'&.extraLarge': {
height: '40px',
},
'&.round.extraLarge': {
borderRadius: '20px',
},
// type
'&.plain': {
color: 'var(--affine-text-primary-color)',
borderColor: 'transparent',
background: 'transparent',
},
'&.primary': {
color: 'var(--affine-pure-white)',
background: 'var(--affine-primary-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.primary:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-primary-color)',
},
'&.primary.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.primary.disabled:not(.without-hover):hover': {
background: 'var(--affine-primary-color)',
},
'&.error': {
color: 'var(--affine-pure-white)',
background: 'var(--affine-error-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.error:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-error-color)',
},
'&.error.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.error.disabled:not(.without-hover):hover': {
background: 'var(--affine-error-color)',
},
'&.warning': {
color: 'var(--affine-white)',
background: 'var(--affine-warning-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.warning:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-warning-color)',
},
'&.warning.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.warning.disabled:not(.without-hover):hover': {
background: 'var(--affine-warning-color)',
},
'&.success': {
color: 'var(--affine-pure-white)',
background: 'var(--affine-success-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.success:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-success-color)',
},
'&.success.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.success.disabled:not(.without-hover):hover': {
background: 'var(--affine-success-color)',
},
'&.processing': {
color: 'var(--affine-pure-white)',
background: 'var(--affine-processing-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)',
},
'&.processing:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-processing-color)',
},
'&.processing.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.processing.disabled:not(.without-hover):hover': {
background: 'var(--affine-processing-color)',
},
},
});
globalStyle(`${button} > span`, {
// flex: 1,
lineHeight: 1,
padding: '0 4px',
});
export const buttonIcon = style({
flexShrink: 0,
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
color: 'var(--affine-icon-color)',
fontSize: '16px',
width: '16px',
height: '16px',
selectors: {
'&.start': {
marginRight: '4px',
},
'&.end': {
marginLeft: '4px',
},
'&.large': {
fontSize: '20px',
width: '20px',
height: '20px',
},
'&.extraLarge': {
fontSize: '20px',
width: '20px',
height: '20px',
},
'&.color-white': {
color: 'var(--affine-white)',
},
},
});
export const iconButton = style({
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
userSelect: 'none',
touchAction: 'manipulation',
outline: '0',
border: '1px solid',
borderRadius: '4px',
transition: 'all .3s',
['WebkitAppRegion' as string]: 'no-drag',
// changeable
width: '24px',
height: '24px',
fontSize: '20px',
color: 'var(--affine-text-primary-color)',
borderColor: 'var(--affine-border-color)',
selectors: {
'&.without-padding': {
margin: '-2px',
},
'&.active': {
color: 'var(--affine-primary-color)',
},
'&:not(.without-hover):hover': {
background: 'var(--affine-hover-color)',
},
'&.disabled': {
opacity: '.4',
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
'&.loading': {
cursor: 'default',
color: 'var(--affine-disable-color)',
pointerEvents: 'none',
},
'&.disabled:not(.without-hover):hover, &.loading:not(.without-hover):hover':
{
background: 'inherit',
},
// size
'&.large': {
width: '32px',
height: '32px',
fontSize: '24px',
},
'&.large.without-padding': {
margin: '-4px',
},
'&.small': { width: '20px', height: '20px', fontSize: '16px' },
'&.extra-small': { width: '16px', height: '16px', fontSize: '12px' },
// type
'&.plain': {
color: 'var(--affine-icon-color)',
borderColor: 'transparent',
background: 'transparent',
},
'&.plain.active': {
color: 'var(--affine-primary-color)',
},
'&.primary': {
color: 'var(--affine-white)',
background: 'var(--affine-primary-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.primary:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-primary-color)',
},
'&.primary.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.primary.disabled:not(.without-hover):hover': {
background: 'var(--affine-primary-color)',
},
'&.error': {
color: 'var(--affine-white)',
background: 'var(--affine-error-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.error:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-error-color)',
},
'&.error.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.error.disabled:not(.without-hover):hover': {
background: 'var(--affine-error-color)',
},
'&.warning': {
color: 'var(--affine-white)',
background: 'var(--affine-warning-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.warning:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-warning-color)',
},
'&.warning.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.warning.disabled:not(.without-hover):hover': {
background: 'var(--affine-warning-color)',
},
'&.success': {
color: 'var(--affine-white)',
background: 'var(--affine-success-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.success:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-success-color)',
},
'&.success.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.success.disabled:not(.without-hover):hover': {
background: 'var(--affine-success-color)',
},
'&.processing': {
color: 'var(--affine-white)',
background: 'var(--affine-processing-color)',
borderColor: 'var(--affine-black-10)',
boxShadow: '0px 1px 2px 0px rgba(255, 255, 255, 0.25) inset',
},
'&.processing:not(.without-hover):hover': {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0%, rgba(0, 0, 0, 0.04) 100%), var(--affine-processing-color)',
},
'&.processing.disabled': {
opacity: '.4',
cursor: 'default',
},
'&.processing.disabled:not(.without-hover):hover': {
background: 'var(--affine-processing-color)',
},
},
});
@@ -1,93 +0,0 @@
import { displayInlineFlex, styled } from '../../styles';
import type { ButtonProps } from './interface';
import { getButtonColors, getSize } from './utils';
export const StyledButton = styled('button', {
shouldForwardProp: prop => {
return ![
'hoverBackground',
'shape',
'hoverColor',
'hoverStyle',
'type',
'bold',
'noBorder',
].includes(prop as string);
},
})<
Pick<
ButtonProps,
| 'size'
| 'disabled'
| 'hoverBackground'
| 'hoverColor'
| 'hoverStyle'
| 'shape'
| 'type'
| 'bold'
| 'noBorder'
>
>(({
theme,
size = 'default',
disabled,
hoverBackground,
hoverColor,
hoverStyle,
bold = false,
shape = 'default',
type = 'default',
noBorder = false,
}) => {
const { fontSize, borderRadius, padding, height } = getSize(size);
return {
height,
paddingLeft: padding,
paddingRight: padding,
border: noBorder ? 'none' : '1px solid',
WebkitAppRegion: 'no-drag',
...displayInlineFlex('center', 'center'),
gap: '8px',
position: 'relative',
// TODO: disabled color is not decided
...(disabled
? {
cursor: 'not-allowed',
pointerEvents: 'none',
color: 'var(--affine-text-disable-color)',
}
: {}),
// TODO: Implement circle shape
borderRadius: shape === 'default' ? borderRadius : height / 2,
fontSize,
fontWeight: bold ? '500' : '400',
'.affine-button-icon': {
color: 'var(--affine-icon-color)',
},
'.affine-button-icon__fixed': {
color: 'var(--affine-icon-color)',
},
'>span': {
width: 'max-content',
},
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
...getButtonColors(theme, type, disabled, {
hoverBackground,
hoverColor,
hoverStyle,
}),
// TODO: disabled hover should be implemented
//
// ':hover': {
// color: hoverColor ?? 'var(--affine-primary-color)',
// background: hoverBackground ?? 'var(--affine-hover-color)',
// '.affine-button-icon':{
//
// }
// ...(hoverStyle ?? {}),
// },
};
});
@@ -1,38 +1,6 @@
import type { Theme } from '@mui/material';
import type { ButtonProps } from './interface';
import { SIZE_DEFAULT, SIZE_MIDDLE, SIZE_SMALL } from './interface';
// TODO: Designer is not sure about the size, Now, is just use default size
export const SIZE_CONFIG = {
[SIZE_SMALL]: {
iconSize: 16,
fontSize: 'var(--affine-font-xs)',
borderRadius: 8,
height: 28,
padding: 12,
},
[SIZE_MIDDLE]: {
iconSize: 20,
fontSize: 'var(--affine-font-sm)',
borderRadius: 8,
height: 32,
padding: 12,
},
[SIZE_DEFAULT]: {
iconSize: 24,
fontSize: 'var(--affine-font-base)',
height: 38,
padding: 24,
borderRadius: 8,
},
} as const;
export const getSize = (
size: typeof SIZE_SMALL | typeof SIZE_MIDDLE | typeof SIZE_DEFAULT
) => {
return SIZE_CONFIG[size];
};
export const getButtonColors = (
_theme: Theme,
@@ -5,21 +5,26 @@ import { type HTMLAttributes, useCallback, useEffect, useRef } from 'react';
import * as icons from './icons';
import * as styles from './index.css';
type CheckboxProps = Omit<HTMLAttributes<HTMLInputElement>, 'onChange'> & {
export type CheckboxProps = Omit<
HTMLAttributes<HTMLInputElement>,
'onChange'
> & {
checked: boolean;
onChange: (
event: React.ChangeEvent<HTMLInputElement>,
checked: boolean
) => void;
disabled?: boolean;
intermediate?: boolean;
indeterminate?: boolean;
animation?: boolean;
};
export const Checkbox = ({
checked,
onChange,
intermediate,
indeterminate: indeterminate,
disabled,
animation,
...otherProps
}: CheckboxProps) => {
const inputRef = useRef<HTMLInputElement>(null);
@@ -28,23 +33,23 @@ export const Checkbox = ({
const newChecked = event.target.checked;
onChange(event, newChecked);
const inputElement = inputRef.current;
if (newChecked && inputElement) {
if (newChecked && inputElement && animation) {
playCheckAnimation(inputElement.parentElement as Element).catch(
console.error
);
}
},
[onChange]
[onChange, animation]
);
useEffect(() => {
if (inputRef.current) {
inputRef.current.indeterminate = !!intermediate;
inputRef.current.indeterminate = !!indeterminate;
}
}, [intermediate]);
}, [indeterminate]);
const icon = intermediate
? icons.intermediate
const icon = indeterminate
? icons.indeterminate
: checked
? icons.checked
: icons.unchecked;
@@ -83,18 +88,21 @@ export const playCheckAnimation = async (refElement: Element) => {
await sparkingEl.animate(
[
{
offset: 0.5,
boxShadow:
'0 -18px 0 -8px #1e96eb, 16px -8px 0 -8px #1e96eb, 16px 8px 0 -8px #1e96eb, 0 18px 0 -8px #1e96eb, -16px 8px 0 -8px #1e96eb, -16px -8px 0 -8px #1e96eb',
},
{
offset: 1,
boxShadow:
'0 -32px 0 -10px transparent, 32px -16px 0 -10px transparent, 32px 16px 0 -10px transparent, 0 36px 0 -10px transparent, -32px 16px 0 -10px transparent, -32px -16px 0 -10px transparent',
},
],
{ duration: 500, easing: 'ease', fill: 'forwards' }
{ duration: 240, easing: 'ease', fill: 'forwards' }
).finished;
await sparkingEl.animate(
[
{
boxShadow:
'0 -36px 0 -10px transparent, 32px -16px 0 -10px transparent, 32px 16px 0 -10px transparent, 0 36px 0 -10px transparent, -32px 16px 0 -10px transparent, -32px -16px 0 -10px transparent',
},
],
{ duration: 360, easing: 'ease', fill: 'forwards' }
).finished;
sparkingEl.remove();
};
@@ -32,7 +32,7 @@ const checked = (
</svg>
);
const intermediate = (
const indeterminate = (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
@@ -49,4 +49,4 @@ const intermediate = (
</svg>
);
export { checked, intermediate, unchecked };
export { checked, indeterminate, unchecked };
@@ -0,0 +1,9 @@
import { style } from '@vanilla-extract/css';
export const root = style({
width: '1em',
height: '1em',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
});
@@ -0,0 +1,840 @@
{
"v": "5.12.1",
"fr": 120,
"ip": 0,
"op": 76,
"w": 300,
"h": 300,
"nm": "合成 1",
"ddd": 0,
"assets": [
{
"id": "comp_0",
"nm": "预合成 1",
"fr": 120,
"layers": [
{
"ddd": 0,
"ind": 1,
"ty": 4,
"nm": "1",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 1,
"k": [
{
"i": {
"x": 0.7,
"y": 1
},
"o": {
"x": 0.3,
"y": 0
},
"t": 0,
"s": [154, 140, 0],
"to": [0, -1.667, 0],
"ti": [0, -15.5, 0]
},
{
"i": {
"x": 0.833,
"y": 0.833
},
"o": {
"x": 0.3,
"y": 0
},
"t": 14.57,
"s": [154, 130, 0],
"to": [0, 15.5, 0],
"ti": [0, -17.167, 0]
},
{
"i": {
"x": 0.5,
"y": 0.5
},
"o": {
"x": 0.167,
"y": 0.167
},
"t": 30,
"s": [154, 233, 0],
"to": [0, 0, 0],
"ti": [0, 0, 0]
},
{
"i": {
"x": 0.833,
"y": 0.833
},
"o": {
"x": 0.5,
"y": 0
},
"t": 171,
"s": [154, 233, 0],
"to": [0, -15.5, 0],
"ti": [0, 15.5, 0]
},
{
"t": 193,
"s": [154, 140, 0]
}
],
"ix": 2,
"l": 2,
"x": "var $bm_rt;\nvar enable, amp, freq, decay, n, t, v;\ntry {\n $bm_rt = enable = effect('Excite - 位置')('Pseudo/BNCA2506f0b33-0001');\n if (enable == 0) {\n $bm_rt = value;\n } else {\n amp = $bm_div(effect('Excite - 位置')('Pseudo/BNCA2506f0b33-0003'), 5);\n freq = $bm_div(effect('Excite - 位置')('Pseudo/BNCA2506f0b33-0004'), 10);\n decay = $bm_div(effect('Excite - 位置')('Pseudo/BNCA2506f0b33-0005'), 3);\n n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : $bm_sub(time, key(n).time), $bm_rt = 0 < n ? (v = velocityAtTime($bm_sub(key(n).time, $bm_div(thisComp.frameDuration, 10))), $bm_sum(value, $bm_div($bm_mul($bm_mul($bm_div(v, 100), amp), Math.sin($bm_mul($bm_mul($bm_mul(freq, t), 2), Math.PI))), Math.exp($bm_mul(decay, t))))) : value;\n }\n} catch (err) {\n $bm_rt = value = value;\n}"
},
"a": {
"a": 0,
"k": [12, 12, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [1246, 1246, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"ef": [
{
"ty": 5,
"nm": "Excite - 位置",
"np": 8,
"mn": "Pseudo/BNCA2506f0b33",
"ix": 1,
"en": 1,
"ef": [
{
"ty": 7,
"nm": "Enable",
"mn": "Pseudo/BNCA2506f0b33-0001",
"ix": 1,
"v": {
"a": 0,
"k": 1,
"ix": 1
}
},
{
"ty": 6,
"nm": "Properties",
"mn": "Pseudo/BNCA2506f0b33-0002",
"ix": 2,
"v": 0
},
{
"ty": 0,
"nm": "Overshoot",
"mn": "Pseudo/BNCA2506f0b33-0003",
"ix": 3,
"v": {
"a": 0,
"k": 20,
"ix": 3,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 0,
"nm": "Bounce",
"mn": "Pseudo/BNCA2506f0b33-0004",
"ix": 4,
"v": {
"a": 0,
"k": 40,
"ix": 4,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 0,
"nm": "Friction",
"mn": "Pseudo/BNCA2506f0b33-0005",
"ix": 5,
"v": {
"a": 0,
"k": 40,
"ix": 5,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 6,
"nm": "",
"mn": "Pseudo/BNCA2506f0b33-0006",
"ix": 6,
"v": 0
}
]
}
],
"shapes": [
{
"ty": "gr",
"it": [
{
"ind": 0,
"ty": "sh",
"ix": 1,
"ks": {
"a": 0,
"k": {
"i": [
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0]
],
"v": [
[7, 8],
[17, 8]
],
"c": false
},
"ix": 2
},
"nm": "路径 1",
"mn": "ADBE Vector Shape - Group",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [0.466666696586, 0.458823559331, 0.490196108351, 1],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 1.5,
"ix": 5
},
"lc": 2,
"lj": 2,
"bm": 0,
"nm": "描边 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [0, 0],
"ix": 2
},
"a": {
"a": 0,
"k": [0, 0],
"ix": 1
},
"s": {
"a": 0,
"k": [100, 100],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "变换"
}
],
"nm": "组 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 1200,
"st": 0,
"ct": 1,
"bm": 0
},
{
"ddd": 0,
"ind": 2,
"ty": 4,
"nm": "2",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 1,
"k": [
{
"i": {
"x": 0.7,
"y": 1
},
"o": {
"x": 0.3,
"y": 0
},
"t": 4,
"s": [154, 140, 0],
"to": [0, -1.667, 0],
"ti": [0, -15.5, 0]
},
{
"i": {
"x": 0.833,
"y": 0.833
},
"o": {
"x": 0.3,
"y": 0
},
"t": 18.57,
"s": [154, 130, 0],
"to": [0, 15.5, 0],
"ti": [0, -17.167, 0]
},
{
"i": {
"x": 0.5,
"y": 0.5
},
"o": {
"x": 0.167,
"y": 0.167
},
"t": 34,
"s": [154, 233, 0],
"to": [0, 0, 0],
"ti": [0, 0, 0]
},
{
"i": {
"x": 0.833,
"y": 0.833
},
"o": {
"x": 0.5,
"y": 0
},
"t": 168,
"s": [154, 233, 0],
"to": [0, -15.5, 0],
"ti": [0, 15.5, 0]
},
{
"t": 190,
"s": [154, 140, 0]
}
],
"ix": 2,
"l": 2,
"x": "var $bm_rt;\nvar enable, amp, freq, decay, n, t, v;\ntry {\n $bm_rt = enable = effect('Excite - 位置')('Pseudo/BNCA2506f0b33-0001');\n if (enable == 0) {\n $bm_rt = value;\n } else {\n amp = $bm_div(effect('Excite - 位置')('Pseudo/BNCA2506f0b33-0003'), 5);\n freq = $bm_div(effect('Excite - 位置')('Pseudo/BNCA2506f0b33-0004'), 10);\n decay = $bm_div(effect('Excite - 位置')('Pseudo/BNCA2506f0b33-0005'), 3);\n n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : $bm_sub(time, key(n).time), $bm_rt = 0 < n ? (v = velocityAtTime($bm_sub(key(n).time, $bm_div(thisComp.frameDuration, 10))), $bm_sum(value, $bm_div($bm_mul($bm_mul($bm_div(v, 100), amp), Math.sin($bm_mul($bm_mul($bm_mul(freq, t), 2), Math.PI))), Math.exp($bm_mul(decay, t))))) : value;\n }\n} catch (err) {\n $bm_rt = value = value;\n}"
},
"a": {
"a": 0,
"k": [12, 12, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [1246, 1246, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"ef": [
{
"ty": 5,
"nm": "Excite - 位置",
"np": 8,
"mn": "Pseudo/BNCA2506f0b33",
"ix": 1,
"en": 1,
"ef": [
{
"ty": 7,
"nm": "Enable",
"mn": "Pseudo/BNCA2506f0b33-0001",
"ix": 1,
"v": {
"a": 0,
"k": 1,
"ix": 1
}
},
{
"ty": 6,
"nm": "Properties",
"mn": "Pseudo/BNCA2506f0b33-0002",
"ix": 2,
"v": 0
},
{
"ty": 0,
"nm": "Overshoot",
"mn": "Pseudo/BNCA2506f0b33-0003",
"ix": 3,
"v": {
"a": 0,
"k": 20,
"ix": 3,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 0,
"nm": "Bounce",
"mn": "Pseudo/BNCA2506f0b33-0004",
"ix": 4,
"v": {
"a": 0,
"k": 40,
"ix": 4,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 0,
"nm": "Friction",
"mn": "Pseudo/BNCA2506f0b33-0005",
"ix": 5,
"v": {
"a": 0,
"k": 40,
"ix": 5,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 6,
"nm": "",
"mn": "Pseudo/BNCA2506f0b33-0006",
"ix": 6,
"v": 0
}
]
}
],
"shapes": [
{
"ty": "gr",
"it": [
{
"ind": 0,
"ty": "sh",
"ix": 1,
"ks": {
"a": 0,
"k": {
"i": [
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0]
],
"v": [
[9, 5],
[15, 5]
],
"c": false
},
"ix": 2
},
"nm": "路径 1",
"mn": "ADBE Vector Shape - Group",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [0.466666696586, 0.458823559331, 0.490196108351, 1],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 1.5,
"ix": 5
},
"lc": 2,
"lj": 2,
"bm": 0,
"nm": "描边 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [0, 0],
"ix": 2
},
"a": {
"a": 0,
"k": [0, 0],
"ix": 1
},
"s": {
"a": 0,
"k": [100, 100],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "变换"
}
],
"nm": "组 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 1200,
"st": 0,
"ct": 1,
"bm": 0
}
]
}
],
"layers": [
{
"ddd": 0,
"ind": 1,
"ty": 4,
"nm": "“图层 4”轮廓",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [154, 140, 0],
"ix": 2,
"l": 2
},
"a": {
"a": 0,
"k": [12, 12, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [1246, 1246, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"ind": 0,
"ty": "sh",
"ix": 1,
"ks": {
"a": 0,
"k": {
"i": [
[-1.105, 0],
[0, 0],
[0, -1.105],
[0, 0],
[1.105, 0],
[0, 0],
[0, 1.105],
[0, 0]
],
"o": [
[0, 0],
[1.105, 0],
[0, 0],
[0, 1.105],
[0, 0],
[-1.105, 0],
[0, 0],
[0, -1.105]
],
"v": [
[-5, -4.5],
[5, -4.5],
[7, -2.5],
[7, 2.5],
[5, 4.5],
[-5, 4.5],
[-7, 2.5],
[-7, -2.5]
],
"c": true
},
"ix": 2
},
"nm": "路径 1",
"mn": "ADBE Vector Shape - Group",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [0.466666696586, 0.458823559331, 0.490196108351, 1],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 1.5,
"ix": 5
},
"lc": 1,
"lj": 2,
"bm": 0,
"nm": "描边 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [12, 15.5],
"ix": 2
},
"a": {
"a": 0,
"k": [0, 0],
"ix": 1
},
"s": {
"a": 0,
"k": [100, 100],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "变换"
}
],
"nm": "组 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 1200,
"st": 0,
"ct": 1,
"bm": 0
},
{
"ddd": 0,
"ind": 2,
"ty": 0,
"nm": "预合成 1",
"refId": "comp_0",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [150, 150, 0],
"ix": 2,
"l": 2
},
"a": {
"a": 0,
"k": [150, 150, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [100, 100, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"hasMask": true,
"masksProperties": [
{
"inv": false,
"mode": "a",
"pt": {
"a": 0,
"k": {
"i": [
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
"v": [
[291.703, 10],
[14, 10],
[14, 128.273],
[291.703, 128.273]
],
"c": true
},
"ix": 1
},
"o": {
"a": 0,
"k": 100,
"ix": 3
},
"x": {
"a": 0,
"k": 0,
"ix": 4
},
"nm": "蒙版 1"
}
],
"w": 300,
"h": 300,
"ip": 0,
"op": 1200,
"st": 0,
"bm": 0
}
],
"markers": [],
"props": {}
}
@@ -0,0 +1,41 @@
import clsx from 'clsx';
import Lottie, { type LottieRef } from 'lottie-react';
import { useEffect, useRef } from 'react';
import * as styles from './collections-icon.css';
import animationData from './collections-icon.json';
export interface CollectionsIconProps {
closed: boolean; // eg, when collections icon is a "dragged over" state
className?: string;
}
// animated collections icon that has two states: closed and opened
export const AnimatedCollectionsIcon = ({
closed,
className,
}: CollectionsIconProps) => {
const lottieRef: LottieRef = useRef(null);
useEffect(() => {
if (lottieRef.current) {
const lottie = lottieRef.current;
if (closed) {
lottie.setDirection(1);
} else {
lottie.setDirection(-1);
}
lottie.play();
}
}, [closed]);
return (
<Lottie
className={clsx(styles.root, className)}
autoPlay={false}
loop={false}
lottieRef={lottieRef}
animationData={animationData}
/>
);
};
@@ -0,0 +1,9 @@
import { style } from '@vanilla-extract/css';
export const root = style({
width: '1em',
height: '1em',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
});
@@ -0,0 +1,989 @@
{
"v": "5.12.1",
"fr": 120,
"ip": 0,
"op": 41,
"w": 240,
"h": 240,
"nm": "Delete",
"ddd": 0,
"assets": [],
"layers": [
{
"ddd": 0,
"ind": 1,
"ty": 4,
"nm": "head",
"parent": 2,
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [12, 5, 0],
"ix": 2,
"l": 2
},
"a": {
"a": 0,
"k": [12, 5, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [100, 100, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"ind": 0,
"ty": "sh",
"ix": 1,
"ks": {
"a": 0,
"k": {
"i": [
[0, 0],
[-1.105, 0],
[0, 0],
[0, -1.105],
[0, 0],
[0, 0]
],
"o": [
[0, -1.105],
[0, 0],
[1.105, 0],
[0, 0],
[0, 0],
[0, 0]
],
"v": [
[-3, 0],
[-1, -2],
[1, -2],
[3, 0],
[3, 2],
[-3, 2]
],
"c": true
},
"ix": 2
},
"nm": "路径 1",
"mn": "ADBE Vector Shape - Group",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [0.466666696586, 0.458823559331, 0.490196108351, 1],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 1.5,
"ix": 5
},
"lc": 1,
"lj": 1,
"ml": 4,
"bm": 0,
"nm": "描边 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [12, 5],
"ix": 2
},
"a": {
"a": 0,
"k": [0, 0],
"ix": 1
},
"s": {
"a": 0,
"k": [100, 100],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "变换"
}
],
"nm": "组 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 1200,
"st": 0,
"ct": 1,
"bm": 0
},
{
"ddd": 0,
"ind": 2,
"ty": 4,
"nm": "headline",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 1,
"k": [
{
"i": {
"x": [0.62],
"y": [1]
},
"o": {
"x": [0.001],
"y": [0]
},
"t": 17.891,
"s": [0]
},
{
"t": 26,
"s": [-23]
}
],
"ix": 10
},
"p": {
"a": 1,
"k": [
{
"i": {
"x": 0.62,
"y": 1
},
"o": {
"x": 0.001,
"y": 0
},
"t": 10,
"s": [119, 67, 0],
"to": [-2.167, -0.583, 0],
"ti": [5.25, 2.583, 0]
},
{
"i": {
"x": 0.62,
"y": 1
},
"o": {
"x": 0.001,
"y": 0
},
"t": 17.891,
"s": [106, 63.5, 0],
"to": [-5.25, -2.583, 0],
"ti": [3.083, 2, 0]
},
{
"t": 25.78125,
"s": [87.5, 51.5, 0]
}
],
"ix": 2,
"l": 2
},
"a": {
"a": 0,
"k": [12, 7, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [1000, 1000, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"ind": 0,
"ty": "sh",
"ix": 1,
"ks": {
"a": 0,
"k": {
"i": [
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0]
],
"v": [
[4, 7],
[20, 7]
],
"c": false
},
"ix": 2
},
"nm": "路径 1",
"mn": "ADBE Vector Shape - Group",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [0.466666696586, 0.458823559331, 0.490196108351, 1],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 1.7,
"ix": 5
},
"lc": 2,
"lj": 2,
"bm": 0,
"nm": "描边 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [0, 0],
"ix": 2
},
"a": {
"a": 0,
"k": [0, 0],
"ix": 1
},
"s": {
"a": 0,
"k": [100, 100],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "变换"
}
],
"nm": "组 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 1200,
"st": 0,
"ct": 1,
"bm": 0
},
{
"ddd": 0,
"ind": 3,
"ty": 4,
"nm": "line2",
"parent": 5,
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [14, 14, 0],
"ix": 2,
"l": 2
},
"a": {
"a": 0,
"k": [14, 14, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [100, 100, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"ind": 0,
"ty": "sh",
"ix": 1,
"ks": {
"a": 0,
"k": {
"i": [
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0]
],
"v": [
[14, 11],
[14, 17]
],
"c": false
},
"ix": 2
},
"nm": "路径 1",
"mn": "ADBE Vector Shape - Group",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [0.466666696586, 0.458823559331, 0.490196108351, 1],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 1.5,
"ix": 5
},
"lc": 2,
"lj": 2,
"bm": 0,
"nm": "描边 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [0, 0],
"ix": 2
},
"a": {
"a": 0,
"k": [0, 0],
"ix": 1
},
"s": {
"a": 0,
"k": [100, 100],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "变换"
}
],
"nm": "组 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 1200,
"st": 0,
"ct": 1,
"bm": 0
},
{
"ddd": 0,
"ind": 4,
"ty": 4,
"nm": "line1",
"parent": 5,
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [10, 14, 0],
"ix": 2,
"l": 2
},
"a": {
"a": 0,
"k": [10, 14, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [100, 100, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"ind": 0,
"ty": "sh",
"ix": 1,
"ks": {
"a": 0,
"k": {
"i": [
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0]
],
"v": [
[10, 11],
[10, 17]
],
"c": false
},
"ix": 2
},
"nm": "路径 1",
"mn": "ADBE Vector Shape - Group",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [0.466666696586, 0.458823559331, 0.490196108351, 1],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 1.5,
"ix": 5
},
"lc": 2,
"lj": 2,
"bm": 0,
"nm": "描边 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [0, 0],
"ix": 2
},
"a": {
"a": 0,
"k": [0, 0],
"ix": 1
},
"s": {
"a": 0,
"k": [100, 100],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "变换"
}
],
"nm": "组 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 1200,
"st": 0,
"ct": 1,
"bm": 0
},
{
"ddd": 0,
"ind": 5,
"ty": 4,
"nm": "body",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 1,
"k": [
{
"i": {
"x": [0.62],
"y": [1]
},
"o": {
"x": [0.001],
"y": [0]
},
"t": 10,
"s": [0]
},
{
"t": 23.80859375,
"s": [-9]
}
],
"ix": 10
},
"p": {
"a": 0,
"k": [49, 207, 0],
"ix": 2,
"l": 2
},
"a": {
"a": 0,
"k": [5, 21, 0],
"ix": 1,
"l": 2
},
"s": {
"a": 0,
"k": [1000, 1000, 100],
"ix": 6,
"l": 2
}
},
"ao": 0,
"ef": [
{
"ty": 5,
"nm": "Excite - 位置",
"np": 8,
"mn": "Pseudo/BNCA2506f0b33",
"ix": 1,
"en": 1,
"ef": [
{
"ty": 7,
"nm": "Enable",
"mn": "Pseudo/BNCA2506f0b33-0001",
"ix": 1,
"v": {
"a": 0,
"k": 1,
"ix": 1
}
},
{
"ty": 6,
"nm": "Properties",
"mn": "Pseudo/BNCA2506f0b33-0002",
"ix": 2,
"v": 0
},
{
"ty": 0,
"nm": "Overshoot",
"mn": "Pseudo/BNCA2506f0b33-0003",
"ix": 3,
"v": {
"a": 0,
"k": 20,
"ix": 3,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 0,
"nm": "Bounce",
"mn": "Pseudo/BNCA2506f0b33-0004",
"ix": 4,
"v": {
"a": 0,
"k": 40,
"ix": 4,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 0,
"nm": "Friction",
"mn": "Pseudo/BNCA2506f0b33-0005",
"ix": 5,
"v": {
"a": 0,
"k": 40,
"ix": 5,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 6,
"nm": "",
"mn": "Pseudo/BNCA2506f0b33-0006",
"ix": 6,
"v": 0
}
]
},
{
"ty": 5,
"nm": "Excite - 旋转",
"np": 8,
"mn": "Pseudo/BNCA2506f0b33",
"ix": 2,
"en": 1,
"ef": [
{
"ty": 7,
"nm": "Enable",
"mn": "Pseudo/BNCA2506f0b33-0001",
"ix": 1,
"v": {
"a": 0,
"k": 1,
"ix": 1
}
},
{
"ty": 6,
"nm": "Properties",
"mn": "Pseudo/BNCA2506f0b33-0002",
"ix": 2,
"v": 0
},
{
"ty": 0,
"nm": "Overshoot",
"mn": "Pseudo/BNCA2506f0b33-0003",
"ix": 3,
"v": {
"a": 0,
"k": 20,
"ix": 3,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 0,
"nm": "Bounce",
"mn": "Pseudo/BNCA2506f0b33-0004",
"ix": 4,
"v": {
"a": 0,
"k": 40,
"ix": 4,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 0,
"nm": "Friction",
"mn": "Pseudo/BNCA2506f0b33-0005",
"ix": 5,
"v": {
"a": 0,
"k": 40,
"ix": 5,
"x": "var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"
}
},
{
"ty": 6,
"nm": "",
"mn": "Pseudo/BNCA2506f0b33-0006",
"ix": 6,
"v": 0
}
]
}
],
"shapes": [
{
"ty": "gr",
"it": [
{
"ind": 0,
"ty": "sh",
"ix": 1,
"ks": {
"a": 0,
"k": {
"i": [
[0, 0],
[0, 0],
[-1.049, 0],
[0, 0],
[-0.075, 1.046],
[0, 0]
],
"o": [
[0, 0],
[0.075, 1.046],
[0, 0],
[1.049, 0],
[0, 0],
[0, 0]
],
"v": [
[-7, -7],
[-6.133, 5.143],
[-4.138, 7],
[4.138, 7],
[6.133, 5.143],
[7, -7]
],
"c": false
},
"ix": 2
},
"nm": "路径 1",
"mn": "ADBE Vector Shape - Group",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [0.466666696586, 0.458823559331, 0.490196108351, 1],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 1.5,
"ix": 5
},
"lc": 1,
"lj": 2,
"bm": 0,
"nm": "描边 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [12, 14],
"ix": 2
},
"a": {
"a": 0,
"k": [0, 0],
"ix": 1
},
"s": {
"a": 0,
"k": [100, 100],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "变换"
}
],
"nm": "组 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 1200,
"st": 0,
"ct": 1,
"bm": 0
}
],
"markers": [],
"props": {}
}
@@ -0,0 +1,38 @@
import clsx from 'clsx';
import Lottie, { type LottieRef } from 'lottie-react';
import { useEffect, useRef } from 'react';
import * as styles from './delete-icon.css';
import animationData from './delete-icon.json';
export interface DeleteIconProps {
closed: boolean; // eg, when delete icon is a "dragged over" state
className?: string;
}
// animated delete icon that has two animation states
export const AnimatedDeleteIcon = ({ closed, className }: DeleteIconProps) => {
const lottieRef: LottieRef = useRef(null);
useEffect(() => {
if (lottieRef.current) {
const lottie = lottieRef.current;
if (closed) {
lottie.setDirection(1);
} else {
lottie.setDirection(-1);
}
lottie.play();
}
}, [closed]);
return (
<Lottie
className={clsx(styles.root, className)}
autoPlay={false}
loop={false}
lottieRef={lottieRef}
animationData={animationData}
/>
);
};
@@ -1,6 +1,6 @@
import * as ScrollArea from '@radix-ui/react-scroll-area';
import clsx from 'clsx';
import { type PropsWithChildren } from 'react';
import { type PropsWithChildren, useRef } from 'react';
import { useHasScrollTop } from '../../components/app-sidebar/sidebar-containers/use-has-scroll-top';
import * as styles from './index.css';
@@ -23,7 +23,8 @@ export const ScrollableContainer = ({
viewPortClassName,
scrollBarClassName,
}: PropsWithChildren<ScrollableContainerProps>) => {
const [hasScrollTop, ref] = useHasScrollTop();
const ref = useRef<HTMLDivElement>(null);
const hasScrollTop = useHasScrollTop(ref);
return (
<ScrollArea.Root
style={_styles}