@astral/ui 1.50.0 → 1.51.1

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 (107) hide show
  1. package/BackdropStack/hooks/useBackdropStackToggle/useBackdropStackToggle.d.ts +2 -2
  2. package/BackdropStack/services/BackdropStackManager/BackdropStackManager.d.ts +30 -2
  3. package/BackdropStack/services/BackdropStackManager/BackdropStackManager.js +35 -3
  4. package/Button/styles.d.ts +1 -1
  5. package/ClickAwayListener/ClickAwayListener.d.ts +9 -0
  6. package/ClickAwayListener/ClickAwayListener.js +14 -0
  7. package/{esm/MenuGroup/types.js → ClickAwayListener/ClickAwayListener.test.d.ts} +0 -0
  8. package/ClickAwayListener/ClickAwayListener.test.js +37 -0
  9. package/ClickAwayListener/index.d.ts +1 -0
  10. package/{DatePicker/DatePickerClickAwayListener → ClickAwayListener}/index.js +1 -1
  11. package/DataGrid/DataGridNoData/styles.d.ts +1 -1
  12. package/DatePicker/DatePicker.d.ts +5 -3
  13. package/DatePicker/DatePicker.js +3 -3
  14. package/DatePicker/DatePicker.test.js +6 -0
  15. package/DatePicker/DatePickerPopper/DatePickerPopper.d.ts +2 -2
  16. package/Fab/styles.d.ts +1 -1
  17. package/IconButton/styles.d.ts +1 -1
  18. package/ListItem/ListItem.d.ts +1 -1
  19. package/ListItem/ListItem.js +1 -13
  20. package/MenuGroup/MenuGroup.d.ts +8 -2
  21. package/MenuGroup/MenuGroup.js +2 -2
  22. package/MenuGroup/stories/styled.d.ts +1 -1
  23. package/MenuGroup/stories/styled.js +2 -2
  24. package/MenuGroup/styles.d.ts +8 -0
  25. package/MenuGroup/{styled.js → styles.js} +10 -5
  26. package/ProductSwitcher/ProductSwitcher.js +1 -1
  27. package/ProductSwitcher/ProductSwitcher.stories.js +8 -1
  28. package/ProductSwitcher/ProductSwitcherContent/ProductSwitcherContent.js +7 -5
  29. package/ProductSwitcher/ProductSwitcherContent/styles.d.ts +6 -30
  30. package/ProductSwitcher/ProductSwitcherContent/styles.js +13 -6
  31. package/ProductSwitcher/styles.d.ts +0 -5
  32. package/ProductSwitcher/styles.js +9 -13
  33. package/ProductSwitcher/types.d.ts +1 -0
  34. package/SwipeableDrawer/styles.d.ts +1 -1
  35. package/Tooltip/styled.d.ts +1 -1
  36. package/esm/BackdropStack/hooks/useBackdropStackToggle/useBackdropStackToggle.d.ts +2 -2
  37. package/esm/BackdropStack/services/BackdropStackManager/BackdropStackManager.d.ts +30 -2
  38. package/esm/BackdropStack/services/BackdropStackManager/BackdropStackManager.js +35 -3
  39. package/esm/Button/styles.d.ts +1 -1
  40. package/esm/ClickAwayListener/ClickAwayListener.d.ts +9 -0
  41. package/esm/ClickAwayListener/ClickAwayListener.js +10 -0
  42. package/esm/ClickAwayListener/ClickAwayListener.test.d.ts +1 -0
  43. package/esm/ClickAwayListener/ClickAwayListener.test.js +35 -0
  44. package/esm/ClickAwayListener/index.d.ts +1 -0
  45. package/esm/ClickAwayListener/index.js +1 -0
  46. package/esm/DataGrid/DataGridNoData/styles.d.ts +1 -1
  47. package/esm/DatePicker/DatePicker.d.ts +5 -3
  48. package/esm/DatePicker/DatePicker.js +3 -3
  49. package/esm/DatePicker/DatePicker.test.js +6 -0
  50. package/esm/DatePicker/DatePickerPopper/DatePickerPopper.d.ts +2 -2
  51. package/esm/Fab/styles.d.ts +1 -1
  52. package/esm/IconButton/styles.d.ts +1 -1
  53. package/esm/ListItem/ListItem.d.ts +1 -1
  54. package/esm/ListItem/ListItem.js +1 -13
  55. package/esm/MenuGroup/MenuGroup.d.ts +8 -2
  56. package/esm/MenuGroup/MenuGroup.js +2 -2
  57. package/esm/MenuGroup/stories/styled.d.ts +1 -1
  58. package/esm/MenuGroup/stories/styled.js +2 -2
  59. package/esm/MenuGroup/styles.d.ts +8 -0
  60. package/esm/MenuGroup/{styled.js → styles.js} +9 -4
  61. package/esm/ProductSwitcher/ProductSwitcher.js +2 -2
  62. package/esm/ProductSwitcher/ProductSwitcher.stories.js +8 -1
  63. package/esm/ProductSwitcher/ProductSwitcherContent/ProductSwitcherContent.js +8 -6
  64. package/esm/ProductSwitcher/ProductSwitcherContent/styles.d.ts +6 -30
  65. package/esm/ProductSwitcher/ProductSwitcherContent/styles.js +12 -5
  66. package/esm/ProductSwitcher/styles.d.ts +0 -5
  67. package/esm/ProductSwitcher/styles.js +8 -12
  68. package/esm/ProductSwitcher/types.d.ts +1 -0
  69. package/esm/SwipeableDrawer/styles.d.ts +1 -1
  70. package/esm/Tooltip/styled.d.ts +1 -1
  71. package/esm/hooks/index.d.ts +2 -0
  72. package/esm/hooks/index.js +2 -0
  73. package/esm/hooks/useClickAwayEffect/index.d.ts +1 -0
  74. package/esm/hooks/useClickAwayEffect/index.js +1 -0
  75. package/esm/hooks/useClickAwayEffect/useClickAwayEffect.d.ts +25 -0
  76. package/esm/hooks/useClickAwayEffect/useClickAwayEffect.js +26 -0
  77. package/esm/hooks/useClickAwayEffect/useClickAwayEffect.test.d.ts +1 -0
  78. package/esm/hooks/useClickAwayEffect/useClickAwayEffect.test.js +42 -0
  79. package/esm/hooks/useEscapeClickEffect/useEscapeClickEffect.d.ts +2 -2
  80. package/esm/index.d.ts +2 -0
  81. package/esm/index.js +2 -0
  82. package/esm/types.d.ts +5 -1
  83. package/hooks/index.d.ts +2 -0
  84. package/hooks/index.js +2 -0
  85. package/hooks/useClickAwayEffect/index.d.ts +1 -0
  86. package/hooks/useClickAwayEffect/index.js +17 -0
  87. package/hooks/useClickAwayEffect/useClickAwayEffect.d.ts +25 -0
  88. package/hooks/useClickAwayEffect/useClickAwayEffect.js +30 -0
  89. package/hooks/useClickAwayEffect/useClickAwayEffect.test.d.ts +1 -0
  90. package/hooks/useClickAwayEffect/useClickAwayEffect.test.js +44 -0
  91. package/hooks/useEscapeClickEffect/useEscapeClickEffect.d.ts +2 -2
  92. package/index.d.ts +2 -0
  93. package/index.js +2 -0
  94. package/package.json +2 -2
  95. package/types.d.ts +5 -1
  96. package/DatePicker/DatePickerClickAwayListener/DatePickerClickAwayListener.d.ts +0 -6
  97. package/DatePicker/DatePickerClickAwayListener/DatePickerClickAwayListener.js +0 -7
  98. package/DatePicker/DatePickerClickAwayListener/index.d.ts +0 -1
  99. package/MenuGroup/styled.d.ts +0 -8
  100. package/MenuGroup/types.d.ts +0 -8
  101. package/MenuGroup/types.js +0 -2
  102. package/esm/DatePicker/DatePickerClickAwayListener/DatePickerClickAwayListener.d.ts +0 -6
  103. package/esm/DatePicker/DatePickerClickAwayListener/DatePickerClickAwayListener.js +0 -3
  104. package/esm/DatePicker/DatePickerClickAwayListener/index.d.ts +0 -1
  105. package/esm/DatePicker/DatePickerClickAwayListener/index.js +0 -1
  106. package/esm/MenuGroup/styled.d.ts +0 -8
  107. package/esm/MenuGroup/types.d.ts +0 -8
@@ -16,42 +16,49 @@ export const handleReject = () => {
16
16
  export const handleGetProducts = () => {
17
17
  return new Promise((resolve) => setTimeout(() => resolve([
18
18
  {
19
+ id: '49d3ce2a-d57c-4794-b659-f80e31ff53b1',
19
20
  url: '',
20
21
  name: 'Астрал.Отчет',
21
22
  logoUrl: 'https://identity.astral.ru/api/Files/06a5fb56-210c-4f08-bb7b-253a9103560f',
22
23
  color: '#2d77ff',
23
24
  },
24
25
  {
26
+ id: '49d3ce2a-d57c-4794-b659-f80e31ff532',
25
27
  url: '',
26
28
  name: 'Астрал.ЭДО',
27
29
  logoUrl: 'https://identity.astral.ru/api/Files/b5b06b5a-2d0e-491b-9815-043d82f104aa',
28
30
  color: 'rgb(117 90 253)',
29
31
  },
30
32
  {
33
+ id: '49d3ce2a-d57c-4794-b659-f80e31ff533',
31
34
  url: '',
32
35
  name: 'Астрал.КЭДО',
33
36
  logoUrl: 'https://identity.astral.ru/api/Files/f0519e97-7a50-4796-a8d2-877cd15c7668',
34
37
  color: 'rgb(117 90 253)',
35
38
  },
36
39
  {
37
- url: '',
40
+ id: '49d3ce2a-d57c-4794-b659-f80e31ff534',
41
+ url: 'https://ofd.astralnalog.ru/lk',
38
42
  name: 'Астрал.ОФД',
39
43
  logoUrl: 'https://identity.astral.ru/api/Files/f0519e97-7a50-4796-a8d2-877cd15c7668',
40
44
  color: 'rgb(117 90 253)',
41
45
  },
42
46
  {
47
+ id: '49d3ce2a-d57c-4794-b659-f80e31ff535',
43
48
  url: '',
44
49
  name: 'Астрал.ЭТ',
45
50
  logoUrl: 'https://identity.astral.ru/api/Files/ac497150-1926-47be-9e5f-42e739e7279c',
46
51
  color: 'rgb(55 103 152)',
47
52
  },
48
53
  {
54
+ id: '49d3ce2a-d57c-4794-b659-f80e31ff536',
49
55
  url: '',
50
56
  name: 'Личный кабинет',
51
57
  logoUrl: 'https://identity.astral.ru/api/Files/9d214f12-c518-44e2-a711-fa1bf2b89fdd',
52
58
  color: 'rgb(10, 124, 255)',
53
59
  },
54
60
  {
61
+ id: '49d3ce2a-d57c-4794-b659-f80e31ff537',
55
62
  url: '',
56
63
  name: 'Кабинет партнера',
57
64
  logoUrl: 'https://identity.astral.ru/api/Files/f0519e97-7a50-4796-a8d2-877cd15c7668',
@@ -1,13 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ErrorFillSm } from '@astral/icons';
2
3
  import { ContentState } from '../../ContentState';
3
- import { Logo, ProductItem } from './styles';
4
+ import { MenuGroup } from '../../MenuGroup';
5
+ import { Typography } from '../../Typography';
6
+ import { Logo, ProductItem, TitleErrorContainer } from './styles';
4
7
  export const ProductSwitcherContent = ({ isLoading, isError, products = [], }) => {
5
8
  return (_jsx(ContentState, Object.assign({ isLoading: isLoading, isCustom: isError, customState: {
6
9
  imgAlt: 'Что-то пошло не так',
7
- title: 'Что-то пошло не так',
10
+ title: (_jsxs(TitleErrorContainer, Object.assign({ container: true, autoFlow: "column", alignItems: "center", justifyContent: "center", component: "span" }, { children: [_jsx(ErrorFillSm, { color: "inherit" }), _jsx(Typography, Object.assign({ variant: "h6", color: "grey", colorIntensity: 900 }, { children: "\u0427\u0442\u043E-\u0442\u043E \u043F\u043E\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A" }))] }))),
8
11
  description: 'Произошла ошибка. Повторите попытку позже.',
9
- // TODO: imgSrc обязательный параметр, а в title не засунуть текст с иконкой. Соответствующая доработка в задаче:
10
- // https://astraltrack.atlassian.net/jira/software/c/projects/UIKIT/boards/142?modal=detail&selectedIssue=UIKIT-435
11
- imgSrc: '',
12
- } }, { children: products.map((product) => (_jsxs(ProductItem, Object.assign({}, product, { children: [_jsx(Logo, { src: product.logoUrl, color: product.color }), product.name] }), product.name))) })));
12
+ } }, { children: _jsx(MenuGroup, Object.assign({ label: "\u041F\u0440\u043E\u0434\u0443\u043A\u0442\u044B \u044D\u043A\u043E\u0441\u0438\u0441\u0442\u0435\u043C\u044B" }, { children: products.map((product) => {
13
+ return (_jsx("li", { children: _jsxs(ProductItem, Object.assign({ component: "a", href: product.url }, { children: [_jsx(Logo, { src: product.logoUrl, color: product.color }), _jsx(Typography, Object.assign({ variant: "ui", color: "grey", colorIntensity: 900 }, { children: product.name }))] })) }, product.id));
14
+ }) })) })));
13
15
  };
@@ -1,35 +1,11 @@
1
1
  /// <reference types="react" />
2
- export declare const ProductItem: import("@emotion/styled").StyledComponent<{
3
- autoFocus?: boolean | undefined;
4
- classes?: Partial<import("@mui/material").MenuItemClasses> | undefined;
5
- dense?: boolean | undefined;
6
- disabled?: boolean | undefined;
7
- disableGutters?: boolean | undefined;
8
- divider?: boolean | undefined;
9
- selected?: boolean | undefined;
10
- sx?: import("@mui/system").SxProps<import("@mui/material").Theme> | undefined;
11
- } & Omit<{
12
- action?: import("react").Ref<import("@mui/material").ButtonBaseActions> | undefined;
13
- centerRipple?: boolean | undefined;
14
- children?: import("react").ReactNode;
15
- classes?: Partial<import("@mui/material").ButtonBaseClasses> | undefined;
16
- disabled?: boolean | undefined;
17
- disableRipple?: boolean | undefined;
18
- disableTouchRipple?: boolean | undefined;
19
- focusRipple?: boolean | undefined;
20
- focusVisibleClassName?: string | undefined;
21
- LinkComponent?: import("react").ElementType<any> | undefined;
22
- onFocusVisible?: import("react").FocusEventHandler<any> | undefined;
23
- sx?: import("@mui/system").SxProps<import("@mui/material").Theme> | undefined;
24
- tabIndex?: number | undefined;
25
- TouchRippleProps?: Partial<import("@mui/material/ButtonBase/TouchRipple").TouchRippleProps> | undefined;
26
- touchRippleRef?: import("react").Ref<import("@mui/material/ButtonBase/TouchRipple").TouchRippleActions> | undefined;
27
- }, "classes"> & import("@mui/material/OverridableComponent").CommonProps & Omit<Pick<import("react").DetailedHTMLProps<import("react").LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "css" | "key" | keyof import("react").LiHTMLAttributes<HTMLLIElement>> & {
28
- ref?: ((instance: HTMLLIElement | null) => void) | import("react").RefObject<HTMLLIElement> | null | undefined;
29
- }, "disabled" | "action" | "divider" | "sx" | "onFocusVisible" | "tabIndex" | "children" | "autoFocus" | "selected" | keyof import("@mui/material/OverridableComponent").CommonProps | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "TouchRippleProps" | "touchRippleRef" | "dense" | "disableGutters"> & {
30
- theme?: import("@emotion/react").Theme | undefined;
31
- }, {}, {}>;
2
+ export declare const ProductItem: import("@mui/material").ExtendButtonBase<import("@mui/material").MenuItemTypeMap<{}, "li">>;
32
3
  export declare const Logo: import("@emotion/styled").StyledComponent<{
33
4
  theme?: import("@emotion/react").Theme | undefined;
34
5
  as?: import("react").ElementType<any> | undefined;
35
6
  }, import("react").DetailedHTMLProps<import("react").ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, {}>;
7
+ export declare const TitleErrorContainer: import("@emotion/styled").StyledComponent<import("../../Grid").GridContainerProps & import("../../Grid").GridElementsProps & {
8
+ children?: import("react").ReactNode;
9
+ } & import("react").RefAttributes<HTMLElement> & {
10
+ theme?: import("@emotion/react").Theme | undefined;
11
+ }, {}, {}>;
@@ -1,15 +1,22 @@
1
1
  import { styled } from '../../styles';
2
2
  import { MenuItem } from '../../MenuItem';
3
+ import { Grid } from '../../Grid';
4
+ // as typeof MenuItem необходим для возможности прокинуть component
5
+ // https://github.com/mui/material-ui/issues/15695
3
6
  export const ProductItem = styled(MenuItem) `
4
- width: 100%;
5
-
6
- border-radius: ${({ theme }) => theme.shape.small};
7
+ padding-left: ${({ theme }) => theme.spacing(6)};
7
8
  `;
8
- export const Logo = styled.img `
9
+ export const Logo = styled('img', {
10
+ shouldForwardProp: (prop) => prop !== 'color',
11
+ }) `
9
12
  width: 40px;
10
13
  height: 40px;
11
- margin-right: ${({ theme }) => theme.spacing(2)};
14
+ margin-right: ${({ theme }) => theme.spacing(4)};
12
15
 
13
16
  background-color: ${({ color }) => color};
14
17
  border-radius: ${({ theme }) => theme.shape.small};
15
18
  `;
19
+ export const TitleErrorContainer = styled(Grid) `
20
+ color: ${({ theme }) => theme.palette.error.dark};
21
+ column-gap: ${({ theme }) => theme.spacing(2)};
22
+ `;
@@ -1,8 +1,3 @@
1
- /// <reference types="react" />
2
- export declare const ContentWrapper: import("@emotion/styled").StyledComponent<{
3
- theme?: import("@emotion/react").Theme | undefined;
4
- as?: import("react").ElementType<any> | undefined;
5
- }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
6
1
  export declare const WidgetMenu: import("@emotion/styled").StyledComponent<import("../Menu").MenuProps & {
7
2
  theme?: import("@emotion/react").Theme | undefined;
8
3
  }, {}, {}>;
@@ -1,17 +1,13 @@
1
1
  import { styled } from '../styles';
2
2
  import { Menu } from '../Menu';
3
- export const ContentWrapper = styled.div `
4
- display: flex;
5
- flex-direction: column;
6
- align-items: center;
7
- justify-content: center;
8
- min-width: 240px;
9
- max-width: 280px;
10
- min-height: 150px;
11
- padding: ${({ theme }) => theme.spacing(2)};
12
- `;
13
3
  export const WidgetMenu = styled(Menu) `
14
- .MuiList-root {
15
- padding: 0;
4
+ .MuiPaper-root > .MuiList-root {
5
+ display: flex;
6
+ flex-direction: column;
7
+ align-items: center;
8
+ justify-content: center;
9
+ width: 285px;
10
+ min-height: 124px;
11
+ padding: ${({ theme }) => theme.spacing(3, 0)};
16
12
  }
17
13
  `;
@@ -1,4 +1,5 @@
1
1
  export type WidgetProduct = {
2
+ id: string;
2
3
  url: string;
3
4
  name: string;
4
5
  logoUrl: string;
@@ -40,7 +40,7 @@ export declare const SwipeableDrawerTitle: import("@emotion/styled").StyledCompo
40
40
  ref?: ((instance: HTMLSpanElement | null) => void) | import("react").RefObject<HTMLSpanElement> | null | undefined;
41
41
  }, "sx" | "children" | "variant" | keyof import("@mui/material/OverridableComponent").CommonProps | ("fontSize" | "fontWeight" | "lineHeight" | "fontFamily" | "alignContent" | "alignItems" | "alignSelf" | "bottom" | "boxShadow" | "boxSizing" | "color" | "columnGap" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontStyle" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "letterSpacing" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "order" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "rowGap" | "textAlign" | "textOverflow" | "textTransform" | "top" | "visibility" | "whiteSpace" | "width" | "zIndex" | "border" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderTop" | "flex" | "gap" | "gridArea" | "gridColumn" | "gridRow" | "margin" | "overflow" | "padding" | "typography" | "p" | "bgcolor" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "displayPrint") | "align" | "gutterBottom" | "noWrap" | "paragraph" | "variantMapping"> & {
42
42
  theme?: import("@emotion/react").Theme | undefined;
43
- } & Omit<import("@mui/material/OverridableComponent").OverrideProps<import("../types").WithoutEmotionSpecific<import("@mui/material").TypographyTypeMap<{}, "span">>, import("react").ElementType<any>>, "color" | "variant"> & {
43
+ } & Omit<import("@mui/material/OverridableComponent").OverrideProps<import("..").WithoutEmotionSpecific<import("@mui/material").TypographyTypeMap<{}, "span">>, import("react").ElementType<any>>, "color" | "variant"> & {
44
44
  variant?: import("@mui/material").TypographyVariant | keyof import("@mui/material").TypographyPropsVariantOverrides | undefined;
45
45
  component?: import("react").ElementType<any> | undefined;
46
46
  color?: "primary" | "secondary" | "red" | "green" | "yellow" | "grey" | "error" | "warning" | "info" | "success" | "text" | "textSecondary" | ((theme: import("@mui/material").Theme) => string) | undefined;
@@ -1,4 +1,4 @@
1
- export declare const StyledTooltip: import("@emotion/styled").StyledComponent<import("../types").WithoutEmotionSpecific<import("@mui/material").TooltipProps> & {
1
+ export declare const StyledTooltip: import("@emotion/styled").StyledComponent<import("..").WithoutEmotionSpecific<import("@mui/material").TooltipProps> & {
2
2
  size?: "medium" | "small" | undefined;
3
3
  } & {
4
4
  theme?: import("@emotion/react").Theme | undefined;
@@ -3,3 +3,5 @@ export * from './useMenu';
3
3
  export * from './useToggle';
4
4
  export * from './useForwardedRef';
5
5
  export * from './useRadioGroup';
6
+ export * from './useEscapeClickEffect';
7
+ export * from './useClickAwayEffect';
@@ -3,3 +3,5 @@ export * from './useMenu';
3
3
  export * from './useToggle';
4
4
  export * from './useForwardedRef';
5
5
  export * from './useRadioGroup';
6
+ export * from './useEscapeClickEffect';
7
+ export * from './useClickAwayEffect';
@@ -0,0 +1 @@
1
+ export * from './useClickAwayEffect';
@@ -0,0 +1 @@
1
+ export * from './useClickAwayEffect';
@@ -0,0 +1,25 @@
1
+ import { RefObject } from 'react';
2
+ import { CloseEventReason } from '../../types';
3
+ export type UseClickAwayListenerOptions = {
4
+ /**
5
+ * @description реф на дом ноду, клик вне которой надо отслеживать
6
+ */
7
+ ref: RefObject<HTMLElement>;
8
+ /**
9
+ * @description колбэк который будет вызываться при нажатии вне рефа
10
+ */
11
+ onClickAway: (e: PointerEvent, reason: CloseEventReason) => void;
12
+ /**
13
+ * @description флаг активности
14
+ */
15
+ isActive: boolean;
16
+ /**
17
+ * @description флаг необходимости предотвращать всплытие, подойдет когда используется внутри модалки
18
+ */
19
+ preventBubbling?: boolean;
20
+ };
21
+ /**
22
+ * @description хук позволяющий подписаться на клик вне указанного рефа,
23
+ * подойдет для использования в кастомных попперах
24
+ */
25
+ export declare const useClickAwayEffect: ({ ref, onClickAway, preventBubbling, isActive, }: UseClickAwayListenerOptions) => void;
@@ -0,0 +1,26 @@
1
+ import { useEffect } from 'react';
2
+ /**
3
+ * @description хук позволяющий подписаться на клик вне указанного рефа,
4
+ * подойдет для использования в кастомных попперах
5
+ */
6
+ export const useClickAwayEffect = ({ ref, onClickAway, preventBubbling, isActive, }) => {
7
+ useEffect(() => {
8
+ const node = ref === null || ref === void 0 ? void 0 : ref.current;
9
+ if (!isActive || !node) {
10
+ return;
11
+ }
12
+ const onClick = (e) => {
13
+ if (!node.contains(e.target)) {
14
+ if (preventBubbling) {
15
+ e.stopPropagation();
16
+ e.stopImmediatePropagation();
17
+ }
18
+ onClickAway(e, 'clickAway');
19
+ }
20
+ };
21
+ window.addEventListener('pointerdown', onClick);
22
+ return () => {
23
+ window.removeEventListener('pointerdown', onClick);
24
+ };
25
+ }, [isActive, ref]);
26
+ };
@@ -0,0 +1,42 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { renderHook, userEvents } from '@astral/tests';
11
+ import { vi } from 'vitest';
12
+ import { useClickAwayEffect } from './useClickAwayEffect';
13
+ describe('useClickAwayEffect', () => {
14
+ it('Props:isActive=true: при нажатии вне целевого дива вызывается onClickAway', () => __awaiter(void 0, void 0, void 0, function* () {
15
+ const onClickAway = vi.fn();
16
+ const div = document.createElement('div');
17
+ document.body.appendChild(div);
18
+ const ref = { current: div };
19
+ renderHook(() => useClickAwayEffect({ isActive: true, onClickAway: onClickAway, ref }));
20
+ yield userEvents.click(document.body);
21
+ expect(onClickAway).toBeCalled();
22
+ }));
23
+ it('Props:isActive=true: при нажатии внутри целевого дива не вызывается onClickAway', () => __awaiter(void 0, void 0, void 0, function* () {
24
+ const onClickAway = vi.fn();
25
+ const div = document.createElement('div');
26
+ document.body.appendChild(div);
27
+ const ref = { current: div };
28
+ renderHook(() => useClickAwayEffect({ isActive: true, onClickAway: onClickAway, ref }));
29
+ yield userEvents.click(div);
30
+ expect(onClickAway).toBeCalledTimes(0);
31
+ }));
32
+ it('Props:isActive=false: при нажатии куда угодно не вызывается onClickAway', () => __awaiter(void 0, void 0, void 0, function* () {
33
+ const onClickAway = vi.fn();
34
+ const div = document.createElement('div');
35
+ document.body.appendChild(div);
36
+ const ref = { current: div };
37
+ renderHook(() => useClickAwayEffect({ isActive: false, onClickAway: onClickAway, ref }));
38
+ yield userEvents.click(document.body);
39
+ yield userEvents.click(div);
40
+ expect(onClickAway).toBeCalledTimes(0);
41
+ }));
42
+ });
@@ -1,9 +1,9 @@
1
- import { Reason } from '../../types';
1
+ import { CloseEventReason } from '../../types';
2
2
  export type UseEscapeClickEffectProps = {
3
3
  /**
4
4
  * @description колбэк который будет вызываться при нажатии на кнопку `esc`
5
5
  */
6
- onEscape?: (event: Event, reason: Reason) => void;
6
+ onEscape?: (event: Event, reason: CloseEventReason) => void;
7
7
  /**
8
8
  * @description флаг активности
9
9
  */
package/esm/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './ActionCell';
2
2
  export * from './Alert';
3
3
  export * from './Autocomplete';
4
+ export * from './ClickAwayListener';
4
5
  export * from './BackdropStack';
5
6
  export * from './Badge';
6
7
  export * from './Button';
@@ -34,6 +35,7 @@ export * from './Grow';
34
35
  export * from './IconButton';
35
36
  export * from './IconDropdownButton';
36
37
  export * from './hooks';
38
+ export * from './types';
37
39
  export * from './List';
38
40
  export * from './ListItem';
39
41
  export * from './ListItemAvatar';
package/esm/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './ActionCell';
2
2
  export * from './Alert';
3
3
  export * from './Autocomplete';
4
+ export * from './ClickAwayListener';
4
5
  export * from './BackdropStack';
5
6
  export * from './Badge';
6
7
  export * from './Button';
@@ -34,6 +35,7 @@ export * from './Grow';
34
35
  export * from './IconButton';
35
36
  export * from './IconDropdownButton';
36
37
  export * from './hooks';
38
+ export * from './types';
37
39
  export * from './List';
38
40
  export * from './ListItem';
39
41
  export * from './ListItemAvatar';
package/esm/types.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  import { AutocompleteCloseReason } from '@mui/base/AutocompleteUnstyled/useAutocomplete';
2
2
  export type WithoutEmotionSpecific<Props> = Omit<Props, 'sx' | 'css'>;
3
- export type Reason = 'escapeKeyDown' | 'backdropClick' | 'toggleInput' | 'blur' | AutocompleteCloseReason | null;
3
+ /**
4
+ * @description список возможных причин закрытия попперов, модалок, тултипов,
5
+ * является абстрактным способом связать сущности всплывашек с BackdropStackManager
6
+ */
7
+ export type CloseEventReason = 'escapeKeyDown' | 'backdropClick' | 'clickAway' | 'toggleInput' | 'blur' | AutocompleteCloseReason | null;
package/hooks/index.d.ts CHANGED
@@ -3,3 +3,5 @@ export * from './useMenu';
3
3
  export * from './useToggle';
4
4
  export * from './useForwardedRef';
5
5
  export * from './useRadioGroup';
6
+ export * from './useEscapeClickEffect';
7
+ export * from './useClickAwayEffect';
package/hooks/index.js CHANGED
@@ -19,3 +19,5 @@ __exportStar(require("./useMenu"), exports);
19
19
  __exportStar(require("./useToggle"), exports);
20
20
  __exportStar(require("./useForwardedRef"), exports);
21
21
  __exportStar(require("./useRadioGroup"), exports);
22
+ __exportStar(require("./useEscapeClickEffect"), exports);
23
+ __exportStar(require("./useClickAwayEffect"), exports);
@@ -0,0 +1 @@
1
+ export * from './useClickAwayEffect';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./useClickAwayEffect"), exports);
@@ -0,0 +1,25 @@
1
+ import { RefObject } from 'react';
2
+ import { CloseEventReason } from '../../types';
3
+ export type UseClickAwayListenerOptions = {
4
+ /**
5
+ * @description реф на дом ноду, клик вне которой надо отслеживать
6
+ */
7
+ ref: RefObject<HTMLElement>;
8
+ /**
9
+ * @description колбэк который будет вызываться при нажатии вне рефа
10
+ */
11
+ onClickAway: (e: PointerEvent, reason: CloseEventReason) => void;
12
+ /**
13
+ * @description флаг активности
14
+ */
15
+ isActive: boolean;
16
+ /**
17
+ * @description флаг необходимости предотвращать всплытие, подойдет когда используется внутри модалки
18
+ */
19
+ preventBubbling?: boolean;
20
+ };
21
+ /**
22
+ * @description хук позволяющий подписаться на клик вне указанного рефа,
23
+ * подойдет для использования в кастомных попперах
24
+ */
25
+ export declare const useClickAwayEffect: ({ ref, onClickAway, preventBubbling, isActive, }: UseClickAwayListenerOptions) => void;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useClickAwayEffect = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * @description хук позволяющий подписаться на клик вне указанного рефа,
7
+ * подойдет для использования в кастомных попперах
8
+ */
9
+ const useClickAwayEffect = ({ ref, onClickAway, preventBubbling, isActive, }) => {
10
+ (0, react_1.useEffect)(() => {
11
+ const node = ref === null || ref === void 0 ? void 0 : ref.current;
12
+ if (!isActive || !node) {
13
+ return;
14
+ }
15
+ const onClick = (e) => {
16
+ if (!node.contains(e.target)) {
17
+ if (preventBubbling) {
18
+ e.stopPropagation();
19
+ e.stopImmediatePropagation();
20
+ }
21
+ onClickAway(e, 'clickAway');
22
+ }
23
+ };
24
+ window.addEventListener('pointerdown', onClick);
25
+ return () => {
26
+ window.removeEventListener('pointerdown', onClick);
27
+ };
28
+ }, [isActive, ref]);
29
+ };
30
+ exports.useClickAwayEffect = useClickAwayEffect;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const tests_1 = require("@astral/tests");
13
+ const vitest_1 = require("vitest");
14
+ const useClickAwayEffect_1 = require("./useClickAwayEffect");
15
+ describe('useClickAwayEffect', () => {
16
+ it('Props:isActive=true: при нажатии вне целевого дива вызывается onClickAway', () => __awaiter(void 0, void 0, void 0, function* () {
17
+ const onClickAway = vitest_1.vi.fn();
18
+ const div = document.createElement('div');
19
+ document.body.appendChild(div);
20
+ const ref = { current: div };
21
+ (0, tests_1.renderHook)(() => (0, useClickAwayEffect_1.useClickAwayEffect)({ isActive: true, onClickAway: onClickAway, ref }));
22
+ yield tests_1.userEvents.click(document.body);
23
+ expect(onClickAway).toBeCalled();
24
+ }));
25
+ it('Props:isActive=true: при нажатии внутри целевого дива не вызывается onClickAway', () => __awaiter(void 0, void 0, void 0, function* () {
26
+ const onClickAway = vitest_1.vi.fn();
27
+ const div = document.createElement('div');
28
+ document.body.appendChild(div);
29
+ const ref = { current: div };
30
+ (0, tests_1.renderHook)(() => (0, useClickAwayEffect_1.useClickAwayEffect)({ isActive: true, onClickAway: onClickAway, ref }));
31
+ yield tests_1.userEvents.click(div);
32
+ expect(onClickAway).toBeCalledTimes(0);
33
+ }));
34
+ it('Props:isActive=false: при нажатии куда угодно не вызывается onClickAway', () => __awaiter(void 0, void 0, void 0, function* () {
35
+ const onClickAway = vitest_1.vi.fn();
36
+ const div = document.createElement('div');
37
+ document.body.appendChild(div);
38
+ const ref = { current: div };
39
+ (0, tests_1.renderHook)(() => (0, useClickAwayEffect_1.useClickAwayEffect)({ isActive: false, onClickAway: onClickAway, ref }));
40
+ yield tests_1.userEvents.click(document.body);
41
+ yield tests_1.userEvents.click(div);
42
+ expect(onClickAway).toBeCalledTimes(0);
43
+ }));
44
+ });
@@ -1,9 +1,9 @@
1
- import { Reason } from '../../types';
1
+ import { CloseEventReason } from '../../types';
2
2
  export type UseEscapeClickEffectProps = {
3
3
  /**
4
4
  * @description колбэк который будет вызываться при нажатии на кнопку `esc`
5
5
  */
6
- onEscape?: (event: Event, reason: Reason) => void;
6
+ onEscape?: (event: Event, reason: CloseEventReason) => void;
7
7
  /**
8
8
  * @description флаг активности
9
9
  */
package/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './ActionCell';
2
2
  export * from './Alert';
3
3
  export * from './Autocomplete';
4
+ export * from './ClickAwayListener';
4
5
  export * from './BackdropStack';
5
6
  export * from './Badge';
6
7
  export * from './Button';
@@ -34,6 +35,7 @@ export * from './Grow';
34
35
  export * from './IconButton';
35
36
  export * from './IconDropdownButton';
36
37
  export * from './hooks';
38
+ export * from './types';
37
39
  export * from './List';
38
40
  export * from './ListItem';
39
41
  export * from './ListItemAvatar';
package/index.js CHANGED
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./ActionCell"), exports);
18
18
  __exportStar(require("./Alert"), exports);
19
19
  __exportStar(require("./Autocomplete"), exports);
20
+ __exportStar(require("./ClickAwayListener"), exports);
20
21
  __exportStar(require("./BackdropStack"), exports);
21
22
  __exportStar(require("./Badge"), exports);
22
23
  __exportStar(require("./Button"), exports);
@@ -50,6 +51,7 @@ __exportStar(require("./Grow"), exports);
50
51
  __exportStar(require("./IconButton"), exports);
51
52
  __exportStar(require("./IconDropdownButton"), exports);
52
53
  __exportStar(require("./hooks"), exports);
54
+ __exportStar(require("./types"), exports);
53
55
  __exportStar(require("./List"), exports);
54
56
  __exportStar(require("./ListItem"), exports);
55
57
  __exportStar(require("./ListItemAvatar"), exports);
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@astral/ui",
3
- "version": "1.50.0",
3
+ "version": "1.51.1",
4
4
  "browser": "./esm/index.js",
5
5
  "main": "./index.js",
6
6
  "dependencies": {
7
- "@astral/icons": "^1.50.0",
7
+ "@astral/icons": "^1.51.1",
8
8
  "@emotion/cache": "11.7.1",
9
9
  "@emotion/react": "11.9.0",
10
10
  "@emotion/server": "11.4.0",
package/types.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  import { AutocompleteCloseReason } from '@mui/base/AutocompleteUnstyled/useAutocomplete';
2
2
  export type WithoutEmotionSpecific<Props> = Omit<Props, 'sx' | 'css'>;
3
- export type Reason = 'escapeKeyDown' | 'backdropClick' | 'toggleInput' | 'blur' | AutocompleteCloseReason | null;
3
+ /**
4
+ * @description список возможных причин закрытия попперов, модалок, тултипов,
5
+ * является абстрактным способом связать сущности всплывашек с BackdropStackManager
6
+ */
7
+ export type CloseEventReason = 'escapeKeyDown' | 'backdropClick' | 'clickAway' | 'toggleInput' | 'blur' | AutocompleteCloseReason | null;
@@ -1,6 +0,0 @@
1
- import { PropsWithChildren } from 'react';
2
- type DatePickerClickAwayListenerProps = {
3
- onClickAway: () => void;
4
- };
5
- export declare const DatePickerClickAwayListener: ({ onClickAway, children, }: PropsWithChildren<DatePickerClickAwayListenerProps>) => JSX.Element;
6
- export {};
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DatePickerClickAwayListener = void 0;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const material_1 = require("@mui/material");
6
- const DatePickerClickAwayListener = ({ onClickAway, children, }) => ((0, jsx_runtime_1.jsx)(material_1.ClickAwayListener, Object.assign({ onClickAway: onClickAway }, { children: (0, jsx_runtime_1.jsx)("div", { children: children }) })));
7
- exports.DatePickerClickAwayListener = DatePickerClickAwayListener;
@@ -1 +0,0 @@
1
- export * from './DatePickerClickAwayListener';