@astral/ui 4.84.0 → 4.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/components/HintPopover/HintPopover.d.ts +6 -0
  2. package/components/HintPopover/HintPopover.js +23 -0
  3. package/components/HintPopover/constants.d.ts +4 -0
  4. package/components/HintPopover/constants.js +5 -0
  5. package/components/HintPopover/index.d.ts +2 -0
  6. package/components/HintPopover/index.js +1 -0
  7. package/components/HintPopover/public.d.ts +2 -0
  8. package/components/HintPopover/public.js +1 -0
  9. package/components/HintPopover/styles.d.ts +38 -0
  10. package/components/HintPopover/styles.js +69 -0
  11. package/components/HintPopover/types.d.ts +24 -0
  12. package/components/HintPopover/types.js +1 -0
  13. package/components/NewPopover/NewPopover.d.ts +1 -1
  14. package/components/NewPopover/NewPopover.js +5 -4
  15. package/components/NewPopover/constants.d.ts +11 -0
  16. package/components/NewPopover/constants.js +11 -0
  17. package/components/NewPopover/styles.js +35 -30
  18. package/components/NewPopover/types.d.ts +5 -0
  19. package/components/NewPopover/useLogic/useLogic.d.ts +4 -3
  20. package/components/NewPopover/useLogic/useLogic.js +17 -8
  21. package/components/NewPopover/useLogic/utils/getArrowPadding/getArrowPadding.d.ts +14 -0
  22. package/components/NewPopover/useLogic/utils/getArrowPadding/getArrowPadding.js +12 -0
  23. package/components/NewPopover/useLogic/utils/getArrowPadding/index.d.ts +1 -0
  24. package/components/NewPopover/useLogic/utils/getArrowPadding/index.js +1 -0
  25. package/components/NewPopover/useLogic/utils/getPopoverCssVars/getPopoverCssVars.d.ts +2 -0
  26. package/components/NewPopover/useLogic/utils/getPopoverCssVars/getPopoverCssVars.js +6 -0
  27. package/components/NewPopover/useLogic/utils/getPopoverCssVars/index.d.ts +1 -0
  28. package/components/NewPopover/useLogic/utils/getPopoverCssVars/index.js +1 -0
  29. package/components/NewPopover/useLogic/utils/resolveAnchorNode/resolveAnchorNode.d.ts +6 -0
  30. package/components/NewPopover/useLogic/utils/resolveAnchorNode/resolveAnchorNode.js +8 -0
  31. package/components/Onboarding/ui/StepStrategy/steps/HighlightStep/HighlightStep.js +3 -4
  32. package/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.d.ts +6 -22
  33. package/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.js +2 -45
  34. package/node/components/HintPopover/HintPopover.d.ts +6 -0
  35. package/node/components/HintPopover/HintPopover.js +27 -0
  36. package/node/components/HintPopover/constants.d.ts +4 -0
  37. package/node/components/HintPopover/constants.js +8 -0
  38. package/node/components/HintPopover/index.d.ts +2 -0
  39. package/node/components/HintPopover/index.js +5 -0
  40. package/node/components/HintPopover/public.d.ts +2 -0
  41. package/node/components/HintPopover/public.js +5 -0
  42. package/node/components/HintPopover/styles.d.ts +38 -0
  43. package/node/components/HintPopover/styles.js +72 -0
  44. package/node/components/HintPopover/types.d.ts +24 -0
  45. package/node/components/HintPopover/types.js +2 -0
  46. package/node/components/NewPopover/NewPopover.d.ts +1 -1
  47. package/node/components/NewPopover/NewPopover.js +5 -4
  48. package/node/components/NewPopover/constants.d.ts +11 -0
  49. package/node/components/NewPopover/constants.js +12 -1
  50. package/node/components/NewPopover/styles.js +34 -29
  51. package/node/components/NewPopover/types.d.ts +5 -0
  52. package/node/components/NewPopover/useLogic/useLogic.d.ts +4 -3
  53. package/node/components/NewPopover/useLogic/useLogic.js +18 -9
  54. package/node/components/NewPopover/useLogic/utils/getArrowPadding/getArrowPadding.d.ts +14 -0
  55. package/node/components/NewPopover/useLogic/utils/getArrowPadding/getArrowPadding.js +16 -0
  56. package/node/components/NewPopover/useLogic/utils/getArrowPadding/index.d.ts +1 -0
  57. package/node/components/NewPopover/useLogic/utils/getArrowPadding/index.js +17 -0
  58. package/node/components/NewPopover/useLogic/utils/getPopoverCssVars/getPopoverCssVars.d.ts +2 -0
  59. package/node/components/NewPopover/useLogic/utils/getPopoverCssVars/getPopoverCssVars.js +10 -0
  60. package/node/components/NewPopover/useLogic/utils/getPopoverCssVars/index.d.ts +1 -0
  61. package/node/components/NewPopover/useLogic/utils/getPopoverCssVars/index.js +5 -0
  62. package/node/components/NewPopover/useLogic/utils/resolveAnchorNode/resolveAnchorNode.d.ts +6 -0
  63. package/node/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/resolveAnchorNode.js +2 -2
  64. package/node/components/Onboarding/ui/StepStrategy/steps/HighlightStep/HighlightStep.js +1 -2
  65. package/node/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.d.ts +6 -22
  66. package/node/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.js +3 -46
  67. package/package.json +1 -1
  68. package/components/NewPopover/utils/resolveAnchorNode.d.ts +0 -6
  69. package/components/NewPopover/utils/resolveAnchorNode.js +0 -8
  70. package/node/components/NewPopover/utils/resolveAnchorNode.d.ts +0 -6
  71. /package/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/index.d.ts +0 -0
  72. /package/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/index.js +0 -0
  73. /package/node/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/index.d.ts +0 -0
  74. /package/node/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/index.js +0 -0
@@ -0,0 +1,6 @@
1
+ import { type HintPopoverProps } from './types';
2
+ /**
3
+ * Поповер-подсказка, привязанная к элементу: подсвечивает возможность интерфейса.
4
+ * Отличие от `NewPopover`: увеличенное скругление, всегда со стрелкой и не сворачивается в BottomDrawer на mobile.
5
+ */
6
+ export declare const HintPopover: ({ variant, title, action, onClose, contentRef, children, className, ...restProps }: HintPopoverProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CrossOutlineMd } from '../../icons/CrossOutlineMd';
3
+ import { useViewportType } from '../useViewportType';
4
+ import { classNames } from '../utils/classNames';
5
+ import { cva } from '../utils/cva';
6
+ import { hintPopoverClassnames } from './constants';
7
+ import { ActionRow, Body, CloseButton, StyledHintPopover, Title, } from './styles';
8
+ const hintPopoverCva = cva(hintPopoverClassnames.root, {
9
+ variants: {
10
+ variant: {
11
+ light: '',
12
+ dark: hintPopoverClassnames.dark,
13
+ },
14
+ },
15
+ });
16
+ /**
17
+ * Поповер-подсказка, привязанная к элементу: подсвечивает возможность интерфейса.
18
+ * Отличие от `NewPopover`: увеличенное скругление, всегда со стрелкой и не сворачивается в BottomDrawer на mobile.
19
+ */
20
+ export const HintPopover = ({ variant = 'dark', title, action, onClose, contentRef, children, className, ...restProps }) => {
21
+ const { isMobile } = useViewportType();
22
+ return (_jsx(StyledHintPopover, { ...restProps, className: classNames(className, hintPopoverCva({ variant })), hasArrow: true, disableMobileDrawer: true, onClose: onClose, children: _jsxs(Body, { ref: contentRef, tabIndex: -1, children: [_jsx(CloseButton, { variant: "text", onClick: onClose, "aria-label": "\u0417\u0430\u043A\u0440\u044B\u0442\u044C", children: _jsx(CrossOutlineMd, {}) }), title && (_jsx(Title, { component: "div", variant: isMobile ? 'h5' : 'h4', children: title })), children, action && _jsx(ActionRow, { children: action })] }) }));
23
+ };
@@ -0,0 +1,4 @@
1
+ export declare const hintPopoverClassnames: {
2
+ root: string;
3
+ dark: string;
4
+ };
@@ -0,0 +1,5 @@
1
+ import { createUIKitClassname } from '../utils/createUIKitClassname';
2
+ export const hintPopoverClassnames = {
3
+ root: createUIKitClassname('hint-popover'),
4
+ dark: createUIKitClassname('hint-popover_dark'),
5
+ };
@@ -0,0 +1,2 @@
1
+ export { HintPopover } from './HintPopover';
2
+ export type { HintPopoverProps, HintPopoverVariant } from './types';
@@ -0,0 +1 @@
1
+ export { HintPopover } from './HintPopover';
@@ -0,0 +1,2 @@
1
+ export { HintPopover } from './HintPopover';
2
+ export type { HintPopoverProps, HintPopoverVariant } from './types';
@@ -0,0 +1 @@
1
+ export { HintPopover } from './HintPopover';
@@ -0,0 +1,38 @@
1
+ /// <reference types="react" />
2
+ /**
3
+ * styled-обёртка над NewPopover: переопределяет его CSS-переменные — всегда
4
+ * увеличенный радиус, а для `dark` ещё тёмную подложку и текст (цвет стрелки
5
+ * подтянется из подложки сам).
6
+ */
7
+ export declare const StyledHintPopover: import("../styled").StyledComponent<import("../NewPopover").NewPopoverProps & {
8
+ theme?: import("@emotion/react").Theme | undefined;
9
+ }, {}, {}>;
10
+ export declare const Body: import("../styled").StyledComponent<{
11
+ theme?: import("@emotion/react").Theme | undefined;
12
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
13
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
14
+ export declare const Title: import("../styled").StyledComponent<import("../Typography/types").TypographyPropsBase & {
15
+ color?: import("../Typography").TypographyColor | undefined;
16
+ variant?: import("../Typography").TypographyVariant | undefined;
17
+ colorIntensity?: import("../Typography").Intensity | undefined;
18
+ component?: import("../Typography/types").ComponentProp | undefined;
19
+ isUpperCase?: boolean | undefined;
20
+ withoutCalt?: boolean | undefined;
21
+ isTabularNums?: boolean | undefined;
22
+ } & import("react").HTMLAttributes<HTMLParagraphElement> & import("react").RefAttributes<HTMLSpanElement> & {
23
+ theme?: import("@emotion/react").Theme | undefined;
24
+ }, {}, {}>;
25
+ export declare const ActionRow: import("../styled").StyledComponent<{
26
+ theme?: import("@emotion/react").Theme | undefined;
27
+ as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
28
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
29
+ export declare const CloseButton: import("../styled").StyledComponent<Omit<import("..").WithoutEmotionSpecific<import("@mui/material").ButtonProps>, "color" | "component" | "size" | "variant" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple"> & {
30
+ variant?: "light" | "link" | "text" | "contained" | "outlined" | undefined;
31
+ loading?: boolean | undefined;
32
+ color?: "primary" | "success" | "warning" | "error" | "grey" | undefined;
33
+ component?: import("react").ElementType | undefined;
34
+ selected?: boolean | undefined;
35
+ size?: "large" | "medium" | undefined;
36
+ } & Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, ""> & import("react").RefAttributes<HTMLButtonElement> & {
37
+ theme?: import("@emotion/react").Theme | undefined;
38
+ }, {}, {}>;
@@ -0,0 +1,69 @@
1
+ import { IconButton } from '../IconButton';
2
+ import { NewPopover } from '../NewPopover';
3
+ import { styled } from '../styled';
4
+ import { Typography } from '../Typography';
5
+ import { hintPopoverClassnames } from './constants';
6
+ /**
7
+ * styled-обёртка над NewPopover: переопределяет его CSS-переменные — всегда
8
+ * увеличенный радиус, а для `dark` ещё тёмную подложку и текст (цвет стрелки
9
+ * подтянется из подложки сам).
10
+ */
11
+ export const StyledHintPopover = styled(NewPopover) `
12
+ --popover-radius: calc(${({ theme }) => theme.shape.medium} * 2);
13
+
14
+ &.${hintPopoverClassnames.dark} {
15
+ --popover-surface-color: ${({ theme }) => theme.palette.grey[900]};
16
+ --popover-text-color: ${({ theme }) => theme.palette.common.white};
17
+ }
18
+ `;
19
+ export const Body = styled.div `
20
+ position: relative;
21
+
22
+ display: flex;
23
+ flex-direction: column;
24
+
25
+ width: min(400px, calc(100vw - ${({ theme }) => theme.spacing(8)}));
26
+ padding: ${({ theme }) => theme.spacing(6)};
27
+
28
+ ${({ theme }) => theme.breakpoints.down('sm')} {
29
+ padding: ${({ theme }) => theme.spacing(4)};
30
+ }
31
+
32
+ /* Крестик висит абсолютом в углу и идёт первым в DOM, поэтому следующий за ним
33
+ верхний элемент (заголовок, а без него — контент) резервирует место справа,
34
+ чтобы текст под крестик не залез. */
35
+ & > button + * {
36
+ padding-right: ${({ theme }) => theme.spacing(10)};
37
+ }
38
+
39
+ /* Тело — программная цель фокуса (tabIndex=-1) у потребителя; рамку убираем. */
40
+ &:focus {
41
+ outline: none;
42
+ }
43
+ `;
44
+ export const Title = styled(Typography) `
45
+ margin-bottom: ${({ theme }) => theme.spacing(4)};
46
+
47
+ ${({ theme }) => theme.breakpoints.down('sm')} {
48
+ margin-bottom: ${({ theme }) => theme.spacing(1)};
49
+ }
50
+ `;
51
+ export const ActionRow = styled.div `
52
+ margin-top: ${({ theme }) => theme.spacing(6)};
53
+
54
+ ${({ theme }) => theme.breakpoints.down('sm')} {
55
+ margin-top: ${({ theme }) => theme.spacing(4)};
56
+ }
57
+ `;
58
+ export const CloseButton = styled(IconButton) `
59
+ position: absolute;
60
+ top: ${({ theme }) => theme.spacing(4)};
61
+ right: ${({ theme }) => theme.spacing(4)};
62
+
63
+ color: inherit;
64
+
65
+ ${({ theme }) => theme.breakpoints.down('sm')} {
66
+ top: ${({ theme }) => theme.spacing(2)};
67
+ right: ${({ theme }) => theme.spacing(2)};
68
+ }
69
+ `;
@@ -0,0 +1,24 @@
1
+ import { type ReactNode, type Ref } from 'react';
2
+ import { type NewPopoverProps } from '../NewPopover';
3
+ /** Цвет подложки highlight-popover. */
4
+ export type HintPopoverVariant = 'light' | 'dark';
5
+ /** Параметры HintPopover */
6
+ export type HintPopoverProps = Omit<NewPopoverProps, 'hasArrow' | 'disableMobileDrawer' | 'title'> & {
7
+ /**
8
+ * Цвет подложки.
9
+ * @default 'dark'
10
+ */
11
+ variant?: HintPopoverVariant;
12
+ /**
13
+ * Заголовок.
14
+ */
15
+ title?: ReactNode;
16
+ /**
17
+ * Слот действий под контентом.
18
+ */
19
+ action?: ReactNode;
20
+ /**
21
+ * Ref на узел контента — для фокус-трапа/определения кликов у потребителя.
22
+ */
23
+ contentRef?: Ref<HTMLDivElement>;
24
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,2 +1,2 @@
1
1
  import { type NewPopoverProps } from './types';
2
- export declare const NewPopover: ({ children, onClose, isOpen, title, className, style, placement, anchorEl, disablePortal, disableAutoFocus, hasArrow, }: NewPopoverProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const NewPopover: ({ children, onClose, isOpen, title, className, style, placement, anchorEl, disablePortal, disableAutoFocus, hasArrow, disableMobileDrawer, }: NewPopoverProps) => import("react/jsx-runtime").JSX.Element;
@@ -15,18 +15,19 @@ const animatedWrapperCva = cva(popoverClassnames.animatedWrapper, {
15
15
  },
16
16
  },
17
17
  });
18
- export const NewPopover = ({ children, onClose, isOpen, title, className, style, placement = 'bottom', anchorEl, disablePortal, disableAutoFocus, hasArrow, }) => {
19
- const { isMobile, isOpened, shouldRender, handleAnimationEnd, handleClose, setContainerRef, setArrowElement, mergedModifiers, } = useLogic({
18
+ export const NewPopover = ({ children, onClose, isOpen, title, className, style, placement = 'bottom', anchorEl, disablePortal, disableAutoFocus, hasArrow, disableMobileDrawer, }) => {
19
+ const { shouldRenderDrawer, isOpened, shouldRender, handleAnimationEnd, handleClose, setContainerRef, setArrowElement, mergedModifiers, animatedWrapperStyle, } = useLogic({
20
20
  isOpen,
21
21
  anchorEl,
22
22
  onClose,
23
23
  disableAutoFocus,
24
24
  hasArrow,
25
+ disableMobileDrawer,
25
26
  });
26
- if (isMobile) {
27
+ if (shouldRenderDrawer) {
27
28
  return (_jsx(BottomDrawer, { title: title, onClose: handleClose, open: isOpened, className: className, style: style, ModalProps: {
28
29
  disableAutoFocus,
29
30
  }, children: children }));
30
31
  }
31
- return (_jsx(StyledMuiPopper, { className: classNames(popoverClassnames.root, className), style: style, open: shouldRender, placement: placement, anchorEl: anchorEl, disablePortal: disablePortal, modifiers: mergedModifiers, children: _jsxs(AnimatedWrapper, { className: animatedWrapperCva({ isOpen: isOpened, hasArrow }), onAnimationEnd: handleAnimationEnd, children: [hasArrow && (_jsx(PopoverArrow, { ref: setArrowElement, className: popoverClassnames.arrow })), _jsx(InnerContainer, { ref: setContainerRef, tabIndex: -1, className: popoverClassnames.innerContainer, children: children })] }) }));
32
+ return (_jsx(StyledMuiPopper, { className: classNames(popoverClassnames.root, className), style: style, open: shouldRender, placement: placement, anchorEl: anchorEl, disablePortal: disablePortal, modifiers: mergedModifiers, children: _jsxs(AnimatedWrapper, { className: animatedWrapperCva({ isOpen: isOpened, hasArrow }), style: animatedWrapperStyle, onAnimationEnd: handleAnimationEnd, children: [hasArrow && (_jsx(PopoverArrow, { ref: setArrowElement, className: popoverClassnames.arrow })), _jsx(InnerContainer, { ref: setContainerRef, tabIndex: -1, className: popoverClassnames.innerContainer, children: children })] }) }));
32
33
  };
@@ -7,6 +7,17 @@ export declare const popoverClassnames: {
7
7
  animatedWrapperHasArrow: string;
8
8
  arrow: string;
9
9
  };
10
+ /** Основание и высота стрелки (px). */
11
+ export declare const ARROW_BASE = 23;
12
+ export declare const ARROW_HEIGHT = 16;
13
+ /** Отступ стрелки от углов (px). */
14
+ export declare const ARROW_PADDING = 24;
15
+ /**
16
+ * Мин. отступ стрелки от угла (px)
17
+ */
18
+ export declare const ARROW_MIN_PADDING = 16;
19
+ /** Мин. «ход» стрелки вдоль кромки (px). */
20
+ export declare const ARROW_MIN_TRACK = 16;
10
21
  /**
11
22
  * Базовые модификаторы Popper.js. У MUI Popper (popper.js)
12
23
  */
@@ -7,6 +7,17 @@ export const popoverClassnames = {
7
7
  animatedWrapperHasArrow: createUIKitClassname('popover__animated-wrapper_has-arrow'),
8
8
  arrow: createUIKitClassname('popover__arrow'),
9
9
  };
10
+ /** Основание и высота стрелки (px). */
11
+ export const ARROW_BASE = 23;
12
+ export const ARROW_HEIGHT = 16;
13
+ /** Отступ стрелки от углов (px). */
14
+ export const ARROW_PADDING = 24;
15
+ /**
16
+ * Мин. отступ стрелки от угла (px)
17
+ */
18
+ export const ARROW_MIN_PADDING = 16;
19
+ /** Мин. «ход» стрелки вдоль кромки (px). */
20
+ export const ARROW_MIN_TRACK = 16;
10
21
  /**
11
22
  * Базовые модификаторы Popper.js. У MUI Popper (popper.js)
12
23
  */
@@ -1,13 +1,15 @@
1
1
  import MuiPopper from '@mui/material/Popper';
2
2
  import { styled } from '../styled';
3
- import { popoverClassnames } from './constants';
3
+ import { ARROW_BASE, ARROW_HEIGHT, popoverClassnames } from './constants';
4
4
  export const StyledMuiPopper = styled(MuiPopper) `
5
5
  &.${popoverClassnames.root} {
6
+ --arrow-base: ${ARROW_BASE}px;
7
+ --arrow-height: ${ARROW_HEIGHT}px;
8
+
6
9
  z-index: ${({ theme }) => theme.zIndex.tooltip};
7
10
  }
8
11
 
9
- /* Anchor ушёл за скролл/вьюпорт — popper вешает reference-hidden.
10
- Стрелка иначе тянется к пропавшему anchor и торчит криво — прячем её. */
12
+ /* Anchor ушёл за скролл/вьюпорт — прячем стрелку. */
11
13
  &[data-popper-reference-hidden] .${popoverClassnames.arrow} {
12
14
  visibility: hidden;
13
15
  }
@@ -36,7 +38,6 @@ export const StyledMuiPopper = styled(MuiPopper) `
36
38
  margin-left: ${({ theme }) => theme.spacing(2)};
37
39
  }
38
40
 
39
- /* Со стрелкой отступ больше */
40
41
  &&[data-popper-placement*='top']
41
42
  .${popoverClassnames.animatedWrapperHasArrow} {
42
43
  margin-bottom: ${({ theme }) => theme.spacing(4)};
@@ -58,54 +59,52 @@ export const StyledMuiPopper = styled(MuiPopper) `
58
59
  }
59
60
 
60
61
  &&[data-popper-placement*='bottom'] .${popoverClassnames.arrow} {
61
- top: -16px;
62
+ top: calc(var(--arrow-height) * -1);
62
63
 
63
- width: 23px;
64
- height: 16px;
64
+ width: var(--arrow-base);
65
+ height: var(--arrow-height);
65
66
 
66
67
  &::before {
67
- border-color: transparent transparent
68
- ${({ theme }) => theme.palette.background.paper};
69
- border-width: 0 11.5px 16px;
68
+ border-color: transparent transparent var(--popover-surface-color, ${({ theme }) => theme.palette.background.paper});
69
+ border-width: 0 calc(var(--arrow-base) / 2) var(--arrow-height);
70
70
  }
71
71
  }
72
72
 
73
73
  &&[data-popper-placement*='top'] .${popoverClassnames.arrow} {
74
- bottom: -16px;
74
+ bottom: calc(var(--arrow-height) * -1);
75
75
 
76
- width: 23px;
77
- height: 16px;
76
+ width: var(--arrow-base);
77
+ height: var(--arrow-height);
78
78
 
79
79
  &::before {
80
- border-color: ${({ theme }) => theme.palette.background.paper} transparent
81
- transparent;
82
- border-width: 16px 11.5px 0;
80
+ border-color: var(--popover-surface-color, ${({ theme }) => theme.palette.background.paper}) transparent transparent;
81
+ border-width: var(--arrow-height) calc(var(--arrow-base) / 2) 0;
83
82
  }
84
83
  }
85
84
 
86
85
  &&[data-popper-placement*='right'] .${popoverClassnames.arrow} {
87
- left: -16px;
86
+ left: calc(var(--arrow-height) * -1);
88
87
 
89
- width: 16px;
90
- height: 23px;
88
+ width: var(--arrow-height);
89
+ height: var(--arrow-base);
91
90
 
92
91
  &::before {
93
- border-color: transparent ${({ theme }) => theme.palette.background.paper}
94
- transparent transparent;
95
- border-width: 11.5px 16px 11.5px 0;
92
+ border-color: transparent var(--popover-surface-color, ${({ theme }) => theme.palette.background.paper}) transparent
93
+ transparent;
94
+ border-width: calc(var(--arrow-base) / 2) var(--arrow-height) calc(var(--arrow-base) / 2) 0;
96
95
  }
97
96
  }
98
97
 
99
98
  &&[data-popper-placement*='left'] .${popoverClassnames.arrow} {
100
- right: -16px;
99
+ right: calc(var(--arrow-height) * -1);
101
100
 
102
- width: 16px;
103
- height: 23px;
101
+ width: var(--arrow-height);
102
+ height: var(--arrow-base);
104
103
 
105
104
  &::before {
106
105
  border-color: transparent transparent transparent
107
- ${({ theme }) => theme.palette.background.paper};
108
- border-width: 11.5px 0 11.5px 16px;
106
+ var(--popover-surface-color, ${({ theme }) => theme.palette.background.paper});
107
+ border-width: calc(var(--arrow-base) / 2) 0 calc(var(--arrow-base) / 2) var(--arrow-height);
109
108
  }
110
109
  }
111
110
  `;
@@ -126,6 +125,8 @@ export const PopoverArrow = styled.span `
126
125
  `;
127
126
  export const AnimatedWrapper = styled.div `
128
127
  position: relative;
128
+
129
+ filter: var(--drop-shadow);
129
130
 
130
131
  animation: popover-grow-out
131
132
  ${({ theme }) => theme.transitions.duration.leavingScreen}ms
@@ -169,8 +170,12 @@ export const InnerContainer = styled.div `
169
170
  &.${popoverClassnames.innerContainer} {
170
171
  overflow: hidden;
171
172
 
172
- background: ${({ theme }) => theme.palette.background.paper};
173
- border-radius: ${({ theme }) => theme.shape.medium};
174
- box-shadow: ${({ theme }) => theme.elevation[200]};
173
+ color: var(--popover-text-color, ${({ theme }) => theme.palette.text.primary});
174
+
175
+ background: var(
176
+ --popover-surface-color,
177
+ ${({ theme }) => theme.palette.background.paper}
178
+ );
179
+ border-radius: var(--popover-radius, ${({ theme }) => theme.shape.medium});
175
180
  }
176
181
  `;
@@ -62,5 +62,10 @@ export type NewPopoverProps = {
62
62
  * @default false
63
63
  */
64
64
  hasArrow?: boolean;
65
+ /**
66
+ * Отключить BottomDrawer на mobile.
67
+ * @default false
68
+ */
69
+ disableMobileDrawer?: boolean;
65
70
  };
66
71
  export {};
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" />
2
2
  import { type NewPopoverModifier, type NewPopoverProps } from '../types';
3
- type UseLogicParams = Pick<NewPopoverProps, 'isOpen' | 'anchorEl' | 'onClose' | 'disableAutoFocus' | 'hasArrow'>;
4
- export declare const useLogic: ({ isOpen, anchorEl, onClose, disableAutoFocus, hasArrow, }: UseLogicParams) => {
5
- isMobile: boolean;
3
+ type UseLogicParams = Pick<NewPopoverProps, 'isOpen' | 'anchorEl' | 'onClose' | 'disableAutoFocus' | 'hasArrow' | 'disableMobileDrawer'>;
4
+ export declare const useLogic: ({ isOpen, anchorEl, onClose, disableAutoFocus, hasArrow, disableMobileDrawer, }: UseLogicParams) => {
5
+ shouldRenderDrawer: boolean;
6
6
  isOpened: boolean;
7
7
  shouldRender: boolean;
8
8
  handleAnimationEnd: () => void;
@@ -11,5 +11,6 @@ export declare const useLogic: ({ isOpen, anchorEl, onClose, disableAutoFocus, h
11
11
  arrowElement: HTMLSpanElement | null;
12
12
  setArrowElement: import("react").Dispatch<import("react").SetStateAction<HTMLSpanElement | null>>;
13
13
  mergedModifiers: NewPopoverModifier[];
14
+ animatedWrapperStyle: import("react").CSSProperties;
14
15
  };
15
16
  export {};
@@ -5,8 +5,10 @@ import { useFocusTrapEffect } from '../../useFocusTrapEffect';
5
5
  import { usePopoverAnimation } from '../../usePopoverAnimation';
6
6
  import { useViewportType } from '../../useViewportType';
7
7
  import { DEFAULT_MODIFIERS } from '../constants';
8
- import { resolveAnchorNode } from '../utils';
9
- export const useLogic = ({ isOpen, anchorEl, onClose, disableAutoFocus, hasArrow, }) => {
8
+ import { getArrowPadding } from './utils/getArrowPadding';
9
+ import { getPopoverCssVars } from './utils/getPopoverCssVars';
10
+ import { resolveAnchorNode } from './utils/resolveAnchorNode';
11
+ export const useLogic = ({ isOpen, anchorEl, onClose, disableAutoFocus, hasArrow, disableMobileDrawer, }) => {
10
12
  const containerRef = useRef(null);
11
13
  const [isContainerMounted, setIsContainerMounted] = useState(false);
12
14
  const [arrowElement, setArrowElement] = useState(null);
@@ -18,7 +20,9 @@ export const useLogic = ({ isOpen, anchorEl, onClose, disableAutoFocus, hasArrow
18
20
  const isControlled = isOpen !== undefined;
19
21
  const { isMobile } = useViewportType();
20
22
  const { shouldRender, handleAnimationEnd } = usePopoverAnimation(isOpened);
21
- const isEffectActive = !isMobile && isOpened && isContainerMounted;
23
+ const animatedWrapperStyle = getPopoverCssVars();
24
+ const shouldRenderDrawer = isMobile && !disableMobileDrawer;
25
+ const isPopoverActive = !shouldRenderDrawer && isOpened && isContainerMounted;
22
26
  const anchorNode = useMemo(() => resolveAnchorNode(anchorEl), [anchorEl]);
23
27
  const excludeNodes = useMemo(() => [anchorNode], [anchorNode]);
24
28
  const handleClose = (event) => {
@@ -27,18 +31,18 @@ export const useLogic = ({ isOpen, anchorEl, onClose, disableAutoFocus, hasArrow
27
31
  useClickAwayEffect({
28
32
  ref: containerRef,
29
33
  onClickAway: handleClose,
30
- isActive: isEffectActive && !isControlled,
34
+ isActive: isPopoverActive && !isControlled,
31
35
  preventBubbling: true,
32
36
  excludeNodes,
33
37
  });
34
38
  useEscapeClickEffect({
35
39
  onEscape: handleClose,
36
- isActive: isEffectActive,
40
+ isActive: isPopoverActive,
37
41
  preventBubbling: true,
38
42
  });
39
43
  useFocusTrapEffect({
40
44
  ref: containerRef,
41
- isActive: isEffectActive && !disableAutoFocus,
45
+ isActive: isPopoverActive && !disableAutoFocus,
42
46
  returnFocusOnDeactivate: true,
43
47
  escapeDeactivates: false,
44
48
  clickOutsideDeactivates: false,
@@ -51,11 +55,15 @@ export const useLogic = ({ isOpen, anchorEl, onClose, disableAutoFocus, hasArrow
51
55
  }
52
56
  return [
53
57
  ...DEFAULT_MODIFIERS,
54
- { name: 'arrow', enabled: true, options: { element: arrowElement } },
58
+ {
59
+ name: 'arrow',
60
+ enabled: true,
61
+ options: { element: arrowElement, padding: getArrowPadding },
62
+ },
55
63
  ];
56
64
  }, [hasArrow, arrowElement]);
57
65
  return {
58
- isMobile,
66
+ shouldRenderDrawer,
59
67
  isOpened,
60
68
  shouldRender,
61
69
  handleAnimationEnd,
@@ -64,5 +72,6 @@ export const useLogic = ({ isOpen, anchorEl, onClose, disableAutoFocus, hasArrow
64
72
  arrowElement,
65
73
  setArrowElement,
66
74
  mergedModifiers,
75
+ animatedWrapperStyle,
67
76
  };
68
77
  };
@@ -0,0 +1,14 @@
1
+ import { type NewPopoverPlacement } from '../../../types';
2
+ type ArrowPaddingArgs = {
3
+ /** Прямоугольник поповера от Popper (нужны только габариты). */
4
+ popper: {
5
+ width: number;
6
+ height: number;
7
+ };
8
+ placement: NewPopoverPlacement;
9
+ };
10
+ /**
11
+ * Фиксированный padding отобразил бы стрелку на скруглённый угол
12
+ */
13
+ export declare const getArrowPadding: ({ popper, placement }: ArrowPaddingArgs) => number;
14
+ export {};
@@ -0,0 +1,12 @@
1
+ import { ARROW_BASE, ARROW_MIN_PADDING, ARROW_MIN_TRACK, ARROW_PADDING, } from '../../../constants';
2
+ /**
3
+ * Фиксированный padding отобразил бы стрелку на скруглённый угол
4
+ */
5
+ export const getArrowPadding = ({ popper, placement }) => {
6
+ const isVertical = placement.startsWith('left') || placement.startsWith('right');
7
+ const side = isVertical ? popper.height : popper.width;
8
+ const free = Math.max(0, side - ARROW_BASE);
9
+ const centerPadding = free / 2;
10
+ const desiredPadding = Math.min(ARROW_PADDING, Math.max(ARROW_MIN_PADDING, (free - ARROW_MIN_TRACK) / 2));
11
+ return Math.min(centerPadding, desiredPadding);
12
+ };
@@ -0,0 +1 @@
1
+ export * from './getArrowPadding';
@@ -0,0 +1 @@
1
+ export * from './getArrowPadding';
@@ -0,0 +1,2 @@
1
+ import type { CSSProperties } from 'react';
2
+ export declare const getPopoverCssVars: () => CSSProperties;
@@ -0,0 +1,6 @@
1
+ export const getPopoverCssVars = () => ({
2
+ // Единая тень на весь силуэт (поповер + уголок стрелки).
3
+ // Эквивалент elevation[200], переведённого в drop-shadow(): box-shadow
4
+ // не умеет обводить единый силуэт поповера со стрелкой.
5
+ '--drop-shadow': 'drop-shadow(0px 0px 1px #072D574F) drop-shadow(0px 3px 5px #072D5733)',
6
+ });
@@ -0,0 +1 @@
1
+ export { getPopoverCssVars } from './getPopoverCssVars';
@@ -0,0 +1 @@
1
+ export { getPopoverCssVars } from './getPopoverCssVars';
@@ -0,0 +1,6 @@
1
+ import { type NewPopoverAnchorEl } from '../../../types';
2
+ /**
3
+ * Приводит anchorEl к DOM-ноде (virtual-anchor → null), чтобы исключить якорь из
4
+ * клика-вне — иначе клик по нему закрывал бы поповер.
5
+ */
6
+ export declare const resolveAnchorNode: (anchorEl: NewPopoverAnchorEl | undefined) => Node | null;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Приводит anchorEl к DOM-ноде (virtual-anchor → null), чтобы исключить якорь из
3
+ * клика-вне — иначе клик по нему закрывал бы поповер.
4
+ */
5
+ export const resolveAnchorNode = (anchorEl) => {
6
+ const value = typeof anchorEl === 'function' ? anchorEl() : anchorEl;
7
+ return value instanceof Node ? value : null;
8
+ };
@@ -1,8 +1,7 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { CrossOutlineMd } from '../../../../../../icons/CrossOutlineMd';
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
2
  import { Typography } from '../../../../../Typography';
4
3
  import { StepFooter } from '../StepFooter';
5
- import { CloseButton, Content, PopoverBody, StepPopover } from './styles';
4
+ import { StepPopover } from './styles';
6
5
  import { useLogic } from './useLogic';
7
6
  /**
8
7
  * Шаг с подсветкой: popover рядом с hole.
@@ -15,5 +14,5 @@ export const HighlightStep = ({ activeStep, isClosing, geometry, }) => {
15
14
  if (!anchorEl) {
16
15
  return null;
17
16
  }
18
- return (_jsx(_Fragment, { children: shouldShowPopover && (_jsx(StepPopover, { isOpen: isOpen, disableAutoFocus: true, hasArrow: true, anchorEl: anchorEl, placement: step.position, children: _jsxs(PopoverBody, { ref: setPopoverNode, tabIndex: -1, children: [_jsx(CloseButton, { variant: "text", onClick: handleClose, "aria-label": "\u0417\u0430\u043A\u0440\u044B\u0442\u044C", children: _jsx(CrossOutlineMd, {}) }), _jsxs(Content, { children: [step.title && (_jsx(Typography, { component: "div", variant: "h5", children: step.title })), step.content && (_jsx(Typography, { component: "div", variant: "body1", color: "grey", colorIntensity: "900", children: step.content }))] }), _jsx(StepFooter, { activeStep: activeStep })] }) })) }));
17
+ return (_jsx(_Fragment, { children: shouldShowPopover && (_jsx(StepPopover, { variant: "light", isOpen: isOpen, disableAutoFocus: true, anchorEl: anchorEl, placement: step.position, onClose: handleClose, contentRef: setPopoverNode, title: step.title, action: _jsx(StepFooter, { activeStep: activeStep }), children: step.content && (_jsx(Typography, { component: "div", variant: "body1", color: "grey", colorIntensity: "900", children: step.content })) })) }));
19
18
  };
@@ -1,25 +1,9 @@
1
1
  /// <reference types="react" />
2
- /**
3
- * Popover шага, z-index над overlay, быстрое закрытие.
4
- */
5
- export declare const StepPopover: import("../../../../../styled").StyledComponent<import("../../../../../NewPopover").NewPopoverProps & {
2
+ export declare const StepPopover: import("../../../../../styled").StyledComponent<Omit<import("../../../../../NewPopover").NewPopoverProps, "title" | "hasArrow" | "disableMobileDrawer"> & {
3
+ variant?: import("../../../../../HintPopover").HintPopoverVariant | undefined;
4
+ title?: import("react").ReactNode;
5
+ action?: import("react").ReactNode;
6
+ contentRef?: import("react").Ref<HTMLDivElement> | undefined;
7
+ } & {
6
8
  theme?: import("@emotion/react").Theme | undefined;
7
9
  }, {}, {}>;
8
- export declare const PopoverBody: import("../../../../../styled").StyledComponent<{
9
- theme?: import("@emotion/react").Theme | undefined;
10
- as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
11
- }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
12
- export declare const CloseButton: import("../../../../../styled").StyledComponent<Omit<import("../../../../..").WithoutEmotionSpecific<import("@mui/material").ButtonProps>, "color" | "component" | "size" | "variant" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple"> & {
13
- variant?: "light" | "link" | "text" | "contained" | "outlined" | undefined;
14
- loading?: boolean | undefined;
15
- color?: "primary" | "success" | "warning" | "error" | "grey" | undefined;
16
- component?: import("react").ElementType | undefined;
17
- selected?: boolean | undefined;
18
- size?: "large" | "medium" | undefined;
19
- } & Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, ""> & import("react").RefAttributes<HTMLButtonElement> & {
20
- theme?: import("@emotion/react").Theme | undefined;
21
- }, {}, {}>;
22
- export declare const Content: import("../../../../../styled").StyledComponent<{
23
- theme?: import("@emotion/react").Theme | undefined;
24
- as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
25
- }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;