Skip to content

Commit

Permalink
feat(PopoutWrapper): add prop strategy and deprecate prop fixed (#…
Browse files Browse the repository at this point in the history
…8217)

* feat(PopoutWrapper): add prop `strategy` and deprecate prop `fixed`

* fix: add todo

* fix: add default value to strategy JSDoc
  • Loading branch information
EldarMuhamethanov authored Feb 3, 2025
1 parent 47c2543 commit 0e4317a
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 8 deletions.
2 changes: 1 addition & 1 deletion packages/vkui/src/components/ActionSheet/ActionSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export const ActionSheet = ({
className={className}
style={style}
onClick={onCloseWithOther}
fixed
strategy="fixed"
>
{actionSheet}
</PopoutWrapper>
Expand Down
1 change: 1 addition & 0 deletions packages/vkui/src/components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ export const Alert = ({
style={style}
onClick={close}
getRootRef={getRootRef}
strategy="fixed"
>
<FocusTrap
{...animationHandlers}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
position: fixed;
}

.absolute {
position: absolute;
}

.overlay {
position: fixed;
inset-inline-start: 0;
Expand All @@ -42,7 +46,8 @@
background: var(--vkui--color_overlay_primary);
}

.fixed .overlay {
.fixed .overlay,
.absolute .overlay {
position: absolute;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ export default story;
type Story = StoryObj<PopoutWrapperProps>;

export const Playground: Story = {
render: (args) => <PopoutWrapper {...args} />,
render: (args) => (
<div style={{ width: 500, height: 500, position: 'relative' }}>
<PopoutWrapper {...args} />
</div>
),
args: {
children: 'Some content',
},
Expand Down
42 changes: 40 additions & 2 deletions packages/vkui/src/components/PopoutWrapper/PopoutWrapper.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { render } from '@testing-library/react';
import { baselineComponent, fakeTimers } from '../../testing/utils';
import { PopoutWrapper } from './PopoutWrapper';
import { PopoutWrapper, type PopoutWrapperProps } from './PopoutWrapper';
import styles from './PopoutWrapper.module.css';

describe(PopoutWrapper, () => {
Expand All @@ -19,8 +19,46 @@ describe(PopoutWrapper, () => {
it('should be closed if closing={true}', () => {
const result = render(<PopoutWrapper closing={true} data-testid="popout-wrapper" />);
const locator = result.getByTestId('popout-wrapper');
expect(locator).not.toHaveClass(styles.opening);
expect(locator).not.toHaveClass(styles.opened);
expect(locator).toHaveClass(styles.closing);
});

const strategyClassNames = [styles.fixed, styles.absolute];
it.each<{ strategy?: PopoutWrapperProps['strategy']; fixed?: boolean; className: string }>([
{
strategy: 'none',
className: '',
},
{
strategy: 'fixed',
className: styles.fixed,
},
{
strategy: 'absolute',
className: styles.absolute,
},
{
fixed: false,
className: '',
},
{
fixed: true,
className: styles.fixed,
},
{
className: styles.fixed,
},
])(
'should have className $className when use strategy $strategy, fixed $fixed',
({ strategy, fixed, className }) => {
const result = render(
<PopoutWrapper strategy={strategy} fixed={fixed} data-testid="popout-wrapper" />,
);
const locator = result.getByTestId('popout-wrapper');
className && expect(locator).toHaveClass(className);
const filteredClassNames = strategyClassNames.filter((cn) => cn !== className).join(' ');
expect(locator).not.toHaveClass(filteredClassNames);
},
);
});
});
27 changes: 25 additions & 2 deletions packages/vkui/src/components/PopoutWrapper/PopoutWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,36 @@ const stylesAlignY = {
bottom: styles.alignYBottom,
};

const stylesStrategy = {
fixed: styles.fixed,
absolute: styles.absolute,
none: undefined,
};

export interface PopoutWrapperProps extends HTMLAttributesWithRootRef<HTMLDivElement> {
/**
* Позволяет сделать прозрачную подложку
*/
noBackground?: boolean;
/**
* @deprecated будет удалён в **VKUI v8**
* Используйте `strategy` вместо этого свойства.
*
* Включает фиксированное позиционирование.
*
* По умолчанию у компонента не задан никакой `position`.
* При значении `false` у компонента не задан никакой `position`.
*/
fixed?: boolean;
/**
* Стратегия позиционирования:
*
* - `fixed`: у контейнера выставлен `position: fixed`
* - `absolute`: у контейнера выставлен `position: absolute`
* - `none`: у контейнера не выставлен `position`
*
* @default 'fixed'
*/
strategy?: 'fixed' | 'absolute' | 'none';
/**
* Выравнивает контент по горизонтали.
*/
Expand All @@ -55,12 +74,16 @@ export const PopoutWrapper = ({
alignX = 'center',
closing = false,
noBackground = false,
strategy: strategyProp,
// TODO [>=8]: удалить свойство
fixed = true,
children,
onClick,
zIndex = 'var(--vkui--z_index_popout)',
...restProps
}: PopoutWrapperProps): React.ReactNode => {
const strategy = strategyProp || (fixed ? 'fixed' : 'none');

return (
<RootComponent
{...restProps}
Expand All @@ -69,7 +92,7 @@ export const PopoutWrapper = ({
stylesAlignY[alignY],
stylesAlignX[alignX],
closing ? styles.closing : styles.opened,
fixed && styles.fixed,
strategy && stylesStrategy[strategy],
!noBackground && styles.masked,
)}
baseStyle={{ zIndex }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const ScreenSpinner: React.FC<ScreenSpinnerProps> & {

return (
<AppRootPortal usePortal={usePortal}>
<PopoutWrapper className={className} style={style} noBackground>
<PopoutWrapper className={className} style={style} noBackground strategy="fixed">
<ScreenSpinnerContainer state={state} mode={mode} label={label} customIcon={customIcon}>
<ScreenSpinnerLoader {...restProps} />
<ScreenSpinnerSwapIcon onClick={onClick} cancelLabel={cancelLabel} />
Expand Down

0 comments on commit 0e4317a

Please sign in to comment.