Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use client';

import * as React from 'react';
import { usePlatform } from '../../hooks/usePlatform';
import { useResizeObserver } from '../../hooks/useResizeObserver';
import { defineComponentDisplayNames } from '../../lib/react/defineComponentDisplayNames';
import type { HasComponent } from '../../types';
import { SplitColContext } from '../SplitCol/SplitColContext';

type SplitColWidthWrapperProps = React.HTMLAttributes<HTMLElement> & HasComponent;

export const SplitColWidthWrapper: React.ForwardRefExoticComponent<
React.PropsWithoutRef<SplitColWidthWrapperProps> & React.RefAttributes<HTMLElement>
// eslint-disable-next-line react/display-name -- используется defineComponentDisplayNames
> = React.forwardRef<HTMLElement, SplitColWidthWrapperProps>(
({ Component = 'div', style, ...restProps }, forwardedRef) => {
const platform = usePlatform();
const { colRef } = React.useContext(SplitColContext);
const [width, setWidth] = React.useState<string | undefined>(undefined);

const doResize = React.useCallback(() => {
if (!colRef?.current) {
setWidth(undefined);
return;
}

const computedStyle = getComputedStyle(colRef.current);

setWidth(
`${
colRef.current.clientWidth -
parseFloat(computedStyle.paddingLeft || '0') -
parseFloat(computedStyle.paddingRight || '0')
}px`,
);
}, [colRef]);

React.useEffect(doResize, [doResize, platform]);
useResizeObserver(colRef, doResize);

return <Component {...restProps} ref={forwardedRef} style={{ width, ...style }} />;
},
);

if (process.env.NODE_ENV !== 'production') {
defineComponentDisplayNames(SplitColWidthWrapper, 'SplitColWidthWrapper');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use client';

import * as React from 'react';
import { defineComponentDisplayNames } from '../../lib/react/defineComponentDisplayNames';
import type { HasComponent } from '../../types';
import { OnboardingTooltipContainer } from './OnboardingTooltipContainer';

type OnboardingTooltipFixedContainerProps = React.HTMLAttributes<HTMLDivElement> & HasComponent;

export const OnboardingTooltipFixedContainer: React.ForwardRefExoticComponent<
React.PropsWithoutRef<OnboardingTooltipFixedContainerProps> & React.RefAttributes<HTMLDivElement>
// eslint-disable-next-line react/display-name -- используется defineComponentDisplayNames
> = React.forwardRef<HTMLDivElement, OnboardingTooltipFixedContainerProps>((props, ref) => (
<OnboardingTooltipContainer {...props} fixed ref={ref} />
));

if (process.env.NODE_ENV !== 'production') {
defineComponentDisplayNames(OnboardingTooltipFixedContainer, 'OnboardingTooltipFixedContainer');
}
12 changes: 8 additions & 4 deletions packages/vkui/src/components/PanelHeader/PanelHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import type {
HasRef,
HTMLAttributesWithRootRef,
} from '../../types';
import { Box } from '../Box/Box';
import { useConfigProvider } from '../ConfigProvider/ConfigProviderContext';
import { FixedLayout } from '../FixedLayout/FixedLayout';
import { SplitColWidthWrapper } from '../FixedLayout/SplitColWidthWrapper';
import { OnboardingTooltipContainer } from '../OnboardingTooltip/OnboardingTooltipContainer';
import { RootComponent } from '../RootComponent/RootComponent';
import { Separator } from '../Separator/Separator';
Expand Down Expand Up @@ -201,15 +202,18 @@ export const PanelHeader = ({
getRootRef={isFixed ? getRootRef : getRef}
>
{isFixed ? (
<FixedLayout
<Box
Component={SplitColWidthWrapper}
className={classNames(styles.fixed, 'vkuiInternalPanelHeader__fixed')}
vertical="top"
position="fixed"
insetBlockStart={0}
inlineSize="100%"
getRootRef={getRef}
>
<PanelHeaderIn before={before} after={after} typographyProps={typographyProps}>
{children}
</PanelHeaderIn>
</FixedLayout>
</Box>
) : (
<PanelHeaderIn before={before} after={after} typographyProps={typographyProps}>
{children}
Expand Down
Comment thread
SevereCloud marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
--vkui_internal--PanelHeaderContext__fade_display: none;

z-index: var(--vkui_internal--z_index_panel_header_context);
inline-size: 100%;
block-size: auto;
}

.viewWidthSmallTabletMinus {
Expand Down Expand Up @@ -171,3 +169,13 @@
opacity: 0;
}
}

/* stylelint-disable selector-max-universal, selector-pseudo-class-disallowed-list */
:global(.vkuiInternalPanelHeader) ~ .host,
:global(.vkuiInternalPanelHeader) ~ * .host {
inset-block-start: calc(
var(--vkui_internal--panel_header_height) +
var(--vkui_internal--safe_area_inset_top)
);
}
/* stylelint-enable selector-max-universal, selector-pseudo-class-disallowed-list */
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { type SizeTypeValues, ViewWidth, type ViewWidthType } from '../../lib/ad
import { useCSSKeyframesAnimationController } from '../../lib/animation';
import type { HTMLAttributesWithRootRef } from '../../types';
import { useScrollLock } from '../AppRoot/ScrollContext';
import { FixedLayout } from '../FixedLayout/FixedLayout';
import { Box } from '../Box/Box';
import { SplitColWidthWrapper } from '../FixedLayout/SplitColWidthWrapper';
import { OnboardingTooltipFixedContainer } from '../OnboardingTooltip/OnboardingTooltipFixedContainer';
import styles from './PanelHeaderContext.module.css';

function getViewWidthClassName(
Expand Down Expand Up @@ -43,6 +45,14 @@ export interface PanelHeaderContextProps extends HTMLAttributesWithRootRef<HTMLD
onClose: VoidFunction;
}

// eslint-disable-next-line react/display-name
const PanelHeaderContextComponent = React.forwardRef<
HTMLElement,
React.AllHTMLAttributes<HTMLElement>
>((props, ref) => (
<SplitColWidthWrapper {...props} ref={ref} Component={OnboardingTooltipFixedContainer} />
));

/**
* @see https://vkui.io/components/panel-header-context
*/
Expand Down Expand Up @@ -82,16 +92,19 @@ export const PanelHeaderContext = ({
}

return (
<FixedLayout
{...restProps}
<Box
Component={PanelHeaderContextComponent}
className={classNames(
styles.host,
platform === 'ios' && styles.ios,
opened ? styles.opened : styles.closing,
getViewWidthClassName(viewWidth, legacySizeX),
className,
)}
vertical="top"
position="fixed"
inlineSize="100%"
insetBlockStart={0}
{...restProps}
>
<div
onClick={(event) => {
Expand All @@ -108,6 +121,6 @@ export const PanelHeaderContext = ({
>
<div className={styles.content}>{children}</div>
</div>
</FixedLayout>
</Box>
);
};
Loading