@astral/ui 4.104.2 → 4.105.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 (79) hide show
  1. package/components/ActionGroup/MainActions/ActionNode/ActionNode.d.ts +9 -0
  2. package/components/ActionGroup/MainActions/ActionNode/ActionNode.js +30 -0
  3. package/components/ActionGroup/MainActions/ActionNode/index.d.ts +1 -0
  4. package/components/ActionGroup/MainActions/ActionNode/index.js +1 -0
  5. package/components/ActionGroup/MainActions/MainActions.d.ts +1 -1
  6. package/components/ActionGroup/MainActions/MainActions.js +3 -14
  7. package/components/ActionGroup/MainActions/hooks/useMainActions/useMainActions.d.ts +352 -3
  8. package/components/ActionGroup/MainActions/hooks/useMainActions/useMainActions.js +33 -6
  9. package/components/ActionGroup/MainActions/index.d.ts +1 -0
  10. package/components/ActionGroup/MainActions/index.js +1 -0
  11. package/components/ActionGroup/MainActions/styles.d.ts +5 -6
  12. package/components/ActionGroup/MainActions/styles.js +6 -7
  13. package/components/ActionGroup/SecondaryVisibleActions/ActionNode/ActionNode.d.ts +12 -0
  14. package/components/ActionGroup/SecondaryVisibleActions/ActionNode/ActionNode.js +30 -0
  15. package/components/ActionGroup/SecondaryVisibleActions/ActionNode/index.d.ts +1 -0
  16. package/components/ActionGroup/SecondaryVisibleActions/ActionNode/index.js +1 -0
  17. package/components/ActionGroup/SecondaryVisibleActions/SecondaryVisibleActions.d.ts +1 -1
  18. package/components/ActionGroup/SecondaryVisibleActions/SecondaryVisibleActions.js +3 -7
  19. package/components/ActionGroup/constants.d.ts +3 -0
  20. package/components/ActionGroup/constants.js +4 -0
  21. package/components/ActionGroup/index.d.ts +2 -1
  22. package/components/ActionGroup/index.js +1 -0
  23. package/components/ActionGroup/public.d.ts +2 -1
  24. package/components/ActionGroup/public.js +1 -0
  25. package/components/ActionGroup/styles.js +5 -0
  26. package/components/ActionGroup/types.d.ts +48 -6
  27. package/components/PageHeader/MobilePageActions/MobilePageActions.js +2 -2
  28. package/components/PageHeader/MobilePageActions/useLogic/useLogic.d.ts +1 -0
  29. package/components/PageHeader/MobilePageActions/useLogic/useLogic.js +3 -0
  30. package/components/PageHeader/PageActions/MainActions/MainActions.d.ts +1 -1
  31. package/components/PageHeader/PageActions/MainActions/MainActions.js +2 -2
  32. package/components/PageHeader/PageActions/MainActions/styles.js +5 -0
  33. package/components/PageHeader/PageActions/PageActions.js +2 -2
  34. package/components/PageHeader/PageActions/SecondaryVisibleActions/SecondaryVisibleActions.d.ts +1 -1
  35. package/components/PageHeader/PageActions/SecondaryVisibleActions/SecondaryVisibleActions.js +3 -3
  36. package/components/PageHeader/PageActions/SecondaryVisibleActions/styles.d.ts +7 -1
  37. package/components/PageHeader/PageActions/useLogic/useLogic.d.ts +1 -0
  38. package/components/PageHeader/PageActions/useLogic/useLogic.js +3 -0
  39. package/components/index.d.ts +1 -1
  40. package/node/components/ActionGroup/MainActions/ActionNode/ActionNode.d.ts +9 -0
  41. package/node/components/ActionGroup/MainActions/ActionNode/ActionNode.js +34 -0
  42. package/node/components/ActionGroup/MainActions/ActionNode/index.d.ts +1 -0
  43. package/node/components/ActionGroup/MainActions/ActionNode/index.js +17 -0
  44. package/node/components/ActionGroup/MainActions/MainActions.d.ts +1 -1
  45. package/node/components/ActionGroup/MainActions/MainActions.js +3 -14
  46. package/node/components/ActionGroup/MainActions/hooks/useMainActions/useMainActions.d.ts +352 -3
  47. package/node/components/ActionGroup/MainActions/hooks/useMainActions/useMainActions.js +33 -6
  48. package/node/components/ActionGroup/MainActions/index.d.ts +1 -0
  49. package/node/components/ActionGroup/MainActions/index.js +1 -0
  50. package/node/components/ActionGroup/MainActions/styles.d.ts +5 -6
  51. package/node/components/ActionGroup/MainActions/styles.js +7 -8
  52. package/node/components/ActionGroup/SecondaryVisibleActions/ActionNode/ActionNode.d.ts +12 -0
  53. package/node/components/ActionGroup/SecondaryVisibleActions/ActionNode/ActionNode.js +34 -0
  54. package/node/components/ActionGroup/SecondaryVisibleActions/ActionNode/index.d.ts +1 -0
  55. package/node/components/ActionGroup/SecondaryVisibleActions/ActionNode/index.js +17 -0
  56. package/node/components/ActionGroup/SecondaryVisibleActions/SecondaryVisibleActions.d.ts +1 -1
  57. package/node/components/ActionGroup/SecondaryVisibleActions/SecondaryVisibleActions.js +3 -7
  58. package/node/components/ActionGroup/constants.d.ts +3 -0
  59. package/node/components/ActionGroup/constants.js +7 -0
  60. package/node/components/ActionGroup/index.d.ts +2 -1
  61. package/node/components/ActionGroup/index.js +3 -1
  62. package/node/components/ActionGroup/public.d.ts +2 -1
  63. package/node/components/ActionGroup/public.js +3 -1
  64. package/node/components/ActionGroup/styles.js +5 -0
  65. package/node/components/ActionGroup/types.d.ts +48 -6
  66. package/node/components/PageHeader/MobilePageActions/MobilePageActions.js +2 -2
  67. package/node/components/PageHeader/MobilePageActions/useLogic/useLogic.d.ts +1 -0
  68. package/node/components/PageHeader/MobilePageActions/useLogic/useLogic.js +3 -0
  69. package/node/components/PageHeader/PageActions/MainActions/MainActions.d.ts +1 -1
  70. package/node/components/PageHeader/PageActions/MainActions/MainActions.js +2 -2
  71. package/node/components/PageHeader/PageActions/MainActions/styles.js +5 -0
  72. package/node/components/PageHeader/PageActions/PageActions.js +2 -2
  73. package/node/components/PageHeader/PageActions/SecondaryVisibleActions/SecondaryVisibleActions.d.ts +1 -1
  74. package/node/components/PageHeader/PageActions/SecondaryVisibleActions/SecondaryVisibleActions.js +3 -3
  75. package/node/components/PageHeader/PageActions/SecondaryVisibleActions/styles.d.ts +7 -1
  76. package/node/components/PageHeader/PageActions/useLogic/useLogic.d.ts +1 -0
  77. package/node/components/PageHeader/PageActions/useLogic/useLogic.js +3 -0
  78. package/node/components/index.d.ts +1 -1
  79. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ export * from './ActionNode';
@@ -1,2 +1,2 @@
1
1
  import type { SecondaryVisibleActionProps } from '../types';
2
- export declare const SecondaryVisibleActions: ({ actions, className, size, }: SecondaryVisibleActionProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const SecondaryVisibleActions: ({ actions, className, size, isRenderActionDisabled, }: SecondaryVisibleActionProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,5 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { IconButton } from '../../IconButton';
3
- import { Tooltip } from '../../Tooltip';
4
- export const SecondaryVisibleActions = ({ actions, className, size, }) => {
5
- return (_jsx(_Fragment, { children: actions.map((action) => {
6
- const { name, icon, disabledReason, disabled, isBlockingOperation, ...mainProps } = action;
7
- return (_jsx(Tooltip, { title: disabled ? disabledReason : name, withoutContainer: !disabled, children: _jsx(IconButton, { variant: "outlined", color: "grey", size: size, name: name, disabled: disabled, className: className, ...mainProps, children: icon }) }, name));
8
- }) }));
2
+ import { ActionNode } from './ActionNode';
3
+ export const SecondaryVisibleActions = ({ actions, className, size = 'medium', isRenderActionDisabled = false, }) => {
4
+ return (_jsx(_Fragment, { children: actions.map((action) => (_jsx(ActionNode, { action: action, size: size, className: className, isRenderActionDisabled: isRenderActionDisabled }, action.name))) }));
9
5
  };
@@ -0,0 +1,3 @@
1
+ export declare const actionGroupClassnames: {
2
+ action: string;
3
+ };
@@ -0,0 +1,4 @@
1
+ import { createUIKitClassname } from '../utils/createUIKitClassname';
2
+ export const actionGroupClassnames = {
3
+ action: createUIKitClassname('action-group__action'),
4
+ };
@@ -1,6 +1,7 @@
1
1
  export { ActionGroup } from './ActionGroup';
2
+ export { actionGroupClassnames } from './constants';
2
3
  export * from './hooks';
3
4
  export { MainActions, useMainActions } from './MainActions';
4
5
  export { SecondaryActions } from './SecondaryActions';
5
6
  export { SecondaryVisibleActions } from './SecondaryVisibleActions';
6
- export type { ActionGroupProps, MainAction, MainActionsProps, SecondaryAction, SecondaryActionProps, SecondaryVisibleAction, SecondaryVisibleActionProps, } from './types';
7
+ export type { ActionElementProps, ActionGroupProps, ActionRenderContext, MainAction, MainActionsProps, NestedActionRenderContext, SecondaryAction, SecondaryActionProps, SecondaryVisibleAction, SecondaryVisibleActionProps, } from './types';
@@ -1,4 +1,5 @@
1
1
  export { ActionGroup } from './ActionGroup';
2
+ export { actionGroupClassnames } from './constants';
2
3
  export * from './hooks';
3
4
  export { MainActions, useMainActions } from './MainActions';
4
5
  export { SecondaryActions } from './SecondaryActions';
@@ -1,6 +1,7 @@
1
1
  export { ActionGroup } from './ActionGroup';
2
+ export { actionGroupClassnames } from './constants';
2
3
  export * from './hooks';
3
4
  export { MainActions, useMainActions } from './MainActions';
4
5
  export { SecondaryActions } from './SecondaryActions';
5
6
  export { SecondaryVisibleActions } from './SecondaryVisibleActions';
6
- export type { ActionGroupProps, MainAction, MainActionsProps, SecondaryActionProps, SecondaryVisibleActionProps, } from './types';
7
+ export type { ActionElementProps, ActionGroupProps, ActionRenderContext, MainAction, MainActionsProps, NestedActionRenderContext, SecondaryActionProps, SecondaryVisibleActionProps, } from './types';
@@ -1,4 +1,5 @@
1
1
  export { ActionGroup } from './ActionGroup';
2
+ export { actionGroupClassnames } from './constants';
2
3
  export * from './hooks';
3
4
  export { MainActions, useMainActions } from './MainActions';
4
5
  export { SecondaryActions } from './SecondaryActions';
@@ -1,5 +1,10 @@
1
1
  import { styled } from '../styled';
2
+ import { actionGroupClassnames } from './constants';
2
3
  export const Wrapper = styled.div `
3
4
  display: flex;
4
5
  gap: ${({ theme }) => theme.spacing(2)};
6
+
7
+ .${actionGroupClassnames.action} {
8
+ flex-grow: 1;
9
+ }
5
10
  `;
@@ -1,9 +1,51 @@
1
- import type { ComponentProps, ElementType, ReactNode } from 'react';
1
+ import type { ComponentProps, ElementType, ReactElement, ReactNode } from 'react';
2
2
  import type { ButtonProps, ButtonSize } from '../Button';
3
3
  import type { DropdownButtonProps } from '../DropdownButton';
4
4
  import type { ListItemButtonProps } from '../ListItemButton';
5
5
  import type { MenuItemProps } from '../MenuItem';
6
6
  import type { TooltipProps } from '../Tooltip';
7
+ /** Свойства стандартного элемента действия, из которых продукт может собрать собственный элемент в `renderAction` */
8
+ export type ActionElementProps = {
9
+ /** Содержимое действия: название */
10
+ children: ReactNode;
11
+ /** Признак блокировки действия */
12
+ disabled?: boolean;
13
+ /** Признак загрузки действия */
14
+ loading?: boolean;
15
+ /** Обработчик нажатия на действие */
16
+ onClick?: ButtonProps['onClick'];
17
+ /** Размер, совпадающий с размером группы действий */
18
+ size: ButtonSize;
19
+ /** Класс, отвечающий за поведение действия в ряду группы */
20
+ className: string;
21
+ };
22
+ /** Контекст renderAction */
23
+ export type ActionRenderContext = {
24
+ /** Стандартный элемент действия */
25
+ defaultElement: ReactElement;
26
+ /** Свойства действия */
27
+ elementProps: ActionElementProps;
28
+ /** DOM-узел действия */
29
+ anchorEl: HTMLElement | null;
30
+ };
31
+ /** Контекст renderAction у действия с выпадающим списком */
32
+ export type NestedActionRenderContext = Pick<ActionRenderContext, 'defaultElement'>;
33
+ type WithRenderAction<TContext = ActionRenderContext> = {
34
+ /**
35
+ * Подменяет отображение действия: стандартный элемент можно обернуть
36
+ * или собрать заново из `elementProps`
37
+ */
38
+ renderAction?: (context: TContext) => ReactNode;
39
+ };
40
+ type WithRenderActionDisabled = {
41
+ /**
42
+ * Отключает вызов `renderAction` — для копии действий, скрытой через css:
43
+ * попап из подмены открывается в портале, и css его не прячет
44
+ *
45
+ * @default false
46
+ */
47
+ isRenderActionDisabled?: boolean;
48
+ };
7
49
  type NestedAction = MenuItemProps & {
8
50
  /** Название действия */
9
51
  text: string;
@@ -33,7 +75,7 @@ export type SingleAction<TMainActionComponent extends ElementType> = Omit<Button
33
75
  * Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонент
34
76
  */
35
77
  component?: TMainActionComponent;
36
- } & Omit<ComponentProps<ElementType extends TMainActionComponent ? 'button' : TMainActionComponent>, ''>;
78
+ } & WithRenderAction & Omit<ComponentProps<ElementType extends TMainActionComponent ? 'button' : TMainActionComponent>, ''>;
37
79
  export type MultipleAction<TMainActionComponent extends ElementType> = Omit<DropdownButtonProps, 'children' | 'name' | 'component'> & {
38
80
  /**
39
81
  * Флаг показа выпадающего списка при клике
@@ -63,7 +105,7 @@ export type MultipleAction<TMainActionComponent extends ElementType> = Omit<Drop
63
105
  * Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонент
64
106
  */
65
107
  component?: TMainActionComponent;
66
- } & Omit<ComponentProps<ElementType extends TMainActionComponent ? 'button' : TMainActionComponent>, ''>;
108
+ } & WithRenderAction<NestedActionRenderContext> & Omit<ComponentProps<ElementType extends TMainActionComponent ? 'button' : TMainActionComponent>, ''>;
67
109
  /** Модель основного экшена */
68
110
  export type MainAction<TMainActionComponent extends ElementType> = SingleAction<TMainActionComponent> | MultipleAction<TMainActionComponent>;
69
111
  export type MainActionsProps<TMainActionComponent extends ElementType> = {
@@ -73,7 +115,7 @@ export type MainActionsProps<TMainActionComponent extends ElementType> = {
73
115
  */
74
116
  isDisabled?: boolean;
75
117
  size?: ButtonSize;
76
- };
118
+ } & WithRenderActionDisabled;
77
119
  /** Модель второстепенного экшена */
78
120
  export type SecondaryAction<TSecondaryActionComponent extends ElementType> = Omit<ListItemButtonProps, 'children' | 'component'> & {
79
121
  /**
@@ -114,7 +156,7 @@ export type SecondaryVisibleAction = Omit<ButtonProps, 'children'> & {
114
156
  * Если true, блокирует взаимодействие с actions
115
157
  */
116
158
  isBlockingOperation?: boolean;
117
- };
159
+ } & WithRenderAction;
118
160
  export type SecondaryVisibleActionProps = {
119
161
  /**
120
162
  * Видимые второстепенные действия
@@ -125,7 +167,7 @@ export type SecondaryVisibleActionProps = {
125
167
  */
126
168
  className?: string;
127
169
  size?: ButtonSize;
128
- };
170
+ } & WithRenderActionDisabled;
129
171
  export type ActionGroupProps<TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType> = {
130
172
  /**
131
173
  * Основные действия
@@ -3,10 +3,10 @@ import { MainActions, SecondaryActions, SecondaryVisibleActions, } from '../Page
3
3
  import { ActionWrapper, SecondaryActionsWrapper, ShowMoreButton, StyledCollapse, StyledMainActions, Wrapper, } from './styles';
4
4
  import { useLogic } from './useLogic';
5
5
  export const MobilePageActions = (props) => {
6
- const { disabledAction, isActive, handleToggle, visibleMainActions, hiddenMainActions, isVisibleShowMoreButton, isLoading, } = useLogic(props);
6
+ const { disabledAction, isRenderActionDisabled, isActive, handleToggle, visibleMainActions, hiddenMainActions, isVisibleShowMoreButton, isLoading, } = useLogic(props);
7
7
  const { secondary, secondaryVisible, className } = props;
8
8
  if (isLoading) {
9
9
  return null;
10
10
  }
11
- return (_jsxs(Wrapper, { className: className, role: "presentation", children: [_jsxs(ActionWrapper, { children: [_jsx(StyledMainActions, { actions: visibleMainActions, isDisabled: disabledAction, "$isVisibleShowMoreButton": isVisibleShowMoreButton, size: "large" }), _jsxs(StyledCollapse, { in: isActive, children: [_jsx(MainActions, { isDisabled: disabledAction, actions: hiddenMainActions, size: "large" }), _jsxs(SecondaryActionsWrapper, { children: [secondaryVisible && (_jsx(SecondaryVisibleActions, { actions: secondaryVisible, size: "large" })), secondary && (_jsx(SecondaryActions, { isDisabled: disabledAction, actions: secondary, size: "large" }))] })] })] }), isVisibleShowMoreButton && (_jsx(ShowMoreButton, { onClick: handleToggle, children: isActive ? 'Скрыть другие действия' : 'Показать другие действия' }))] }));
11
+ return (_jsxs(Wrapper, { className: className, role: "presentation", children: [_jsxs(ActionWrapper, { children: [_jsx(StyledMainActions, { actions: visibleMainActions, isDisabled: disabledAction, "$isVisibleShowMoreButton": isVisibleShowMoreButton, size: "large", isRenderActionDisabled: isRenderActionDisabled }), _jsxs(StyledCollapse, { in: isActive, children: [_jsx(MainActions, { isDisabled: disabledAction, actions: hiddenMainActions, size: "large", isRenderActionDisabled: isRenderActionDisabled }), _jsxs(SecondaryActionsWrapper, { children: [secondaryVisible && (_jsx(SecondaryVisibleActions, { actions: secondaryVisible, size: "large", isRenderActionDisabled: true })), secondary && (_jsx(SecondaryActions, { isDisabled: disabledAction, actions: secondary, size: "large" }))] })] })] }), isVisibleShowMoreButton && (_jsx(ShowMoreButton, { onClick: handleToggle, children: isActive ? 'Скрыть другие действия' : 'Показать другие действия' }))] }));
12
12
  };
@@ -3,6 +3,7 @@ import { type MobilePageActionsProps } from '../MobilePageActions';
3
3
  type UseLogicParams<TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType> = MobilePageActionsProps<TMainActionComponent, TSecondaryActionComponent>;
4
4
  export declare const useLogic: <TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType>({ main, secondary, secondaryVisible, isLoading, }: UseLogicParams<TMainActionComponent, TSecondaryActionComponent>) => {
5
5
  disabledAction: boolean;
6
+ isRenderActionDisabled: boolean;
6
7
  isActive: boolean;
7
8
  handleToggle: () => void;
8
9
  visibleMainActions: import("../../../ActionGroup").MainAction<TMainActionComponent>[] | undefined;
@@ -1,8 +1,10 @@
1
1
  import { useState } from 'react';
2
2
  import { useActionsState } from '../../../ActionGroup';
3
+ import { useViewportType } from '../../../useViewportType';
3
4
  export const useLogic = ({ main, secondary, secondaryVisible, isLoading, }) => {
4
5
  const [isActive, setIsActive] = useState(false);
5
6
  const { disabledAction } = useActionsState({ main, secondary });
7
+ const { isMobile } = useViewportType();
6
8
  const handleToggle = () => {
7
9
  setIsActive(!isActive);
8
10
  };
@@ -10,6 +12,7 @@ export const useLogic = ({ main, secondary, secondaryVisible, isLoading, }) => {
10
12
  const hiddenMainActions = main?.slice(2);
11
13
  return {
12
14
  disabledAction,
15
+ isRenderActionDisabled: !isMobile,
13
16
  isActive,
14
17
  handleToggle,
15
18
  visibleMainActions,
@@ -13,5 +13,5 @@ type PageMainActionsProps<TMainActionComponent extends ElementType> = Omit<MainA
13
13
  */
14
14
  spacing?: number;
15
15
  };
16
- export declare const MainActions: <TMainActionComponent extends ElementType = ElementType>({ actions, isDisabled, className, size, spacing, }: PageMainActionsProps<TMainActionComponent>) => import("react/jsx-runtime").JSX.Element | null;
16
+ export declare const MainActions: <TMainActionComponent extends ElementType = ElementType>({ actions, isDisabled, className, size, spacing, isRenderActionDisabled, }: PageMainActionsProps<TMainActionComponent>) => import("react/jsx-runtime").JSX.Element | null;
17
17
  export {};
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { MainActions as ActionGroupMainActions, } from '../../../ActionGroup';
3
3
  import { Wrapper } from './styles';
4
- export const MainActions = ({ actions, isDisabled, className, size, spacing = 2, }) => {
4
+ export const MainActions = ({ actions, isDisabled, className, size, spacing = 2, isRenderActionDisabled, }) => {
5
5
  if (!actions || (actions && actions.length === 0)) {
6
6
  return null;
7
7
  }
8
- return (_jsx(Wrapper, { className: className, "$spacing": spacing, children: _jsx(ActionGroupMainActions, { actions: actions ?? [], isDisabled: isDisabled, size: size }) }));
8
+ return (_jsx(Wrapper, { className: className, "$spacing": spacing, children: _jsx(ActionGroupMainActions, { actions: actions ?? [], isDisabled: isDisabled, size: size, isRenderActionDisabled: isRenderActionDisabled }) }));
9
9
  };
@@ -1,10 +1,15 @@
1
1
  import { buttonClasses } from '@mui/material/Button';
2
+ import { actionGroupClassnames } from '../../../ActionGroup';
2
3
  import { styled } from '../../../styled';
3
4
  import { tooltipClassnames } from '../../../Tooltip';
4
5
  export const Wrapper = styled.div `
5
6
  display: flex;
6
7
  gap: ${({ theme, $spacing }) => theme.spacing($spacing)};
7
8
 
9
+ .${actionGroupClassnames.action} {
10
+ flex-grow: 1;
11
+ }
12
+
8
13
  ${({ theme }) => theme.breakpoints.down('mobile')} {
9
14
  flex-wrap: wrap;
10
15
  gap: ${({ theme }) => theme.spacing(2)};
@@ -11,10 +11,10 @@ import { ActionWrapper, CollapsedActionsWrapper, FocusModeButton, MainActionsWra
11
11
  import { useLogic } from './useLogic';
12
12
  const PageActionsInner = (props, ref) => {
13
13
  const { secondary, secondaryVisible, main, className, isLoading, size = 'medium', spacing = 2, } = props;
14
- const { disabledAction, buttonClassnames, isFocusedMode, handleClick, tooltipTitle, collapsedActions, classnames, } = useLogic(props);
14
+ const { disabledAction, isRenderActionDisabled, buttonClassnames, isFocusedMode, handleClick, tooltipTitle, collapsedActions, classnames, } = useLogic(props);
15
15
  if (isLoading) {
16
16
  return (_jsx(Wrapper, { children: _jsx(PageActionSkeleton, { size: size }) }));
17
17
  }
18
- return (_jsx(Wrapper, { className: className, ref: ref, children: _jsxs(ActionWrapper, { "$spacing": spacing, children: [_jsx(Tooltip, { title: tooltipTitle, enterDelay: 400, enterNextDelay: 400, placement: "bottom-end", children: _jsx(FocusModeButton, { className: buttonClassnames, variant: "outlined", onClick: handleClick, "aria-label": tooltipTitle, color: "grey", children: isFocusedMode ? _jsx(MinimizeOutlineMd, {}) : _jsx(FullSizeOutlineMd, {}) }) }), _jsx(MainActionsWrapper, { "$spacing": spacing, className: classnames, children: _jsx(MainActions, { isDisabled: disabledAction, actions: main, size: size, spacing: spacing }) }), (secondaryVisible || secondary) && (_jsxs(SecondaryVisibleWrapper, { "$spacing": spacing, className: classnames, children: [secondaryVisible && (_jsx(SecondaryVisibleActions, { actions: secondaryVisible, size: size })), secondary && (_jsx(SecondaryActions, { isDisabled: disabledAction, actions: secondary, size: size }))] })), collapsedActions.length > 0 && (_jsx(CollapsedActionsWrapper, { className: classnames, children: _jsx(SecondaryActions, { isDisabled: disabledAction, actions: collapsedActions, size: size }) }))] }) }));
18
+ return (_jsx(Wrapper, { className: className, ref: ref, children: _jsxs(ActionWrapper, { "$spacing": spacing, children: [_jsx(Tooltip, { title: tooltipTitle, enterDelay: 400, enterNextDelay: 400, placement: "bottom-end", children: _jsx(FocusModeButton, { className: buttonClassnames, variant: "outlined", onClick: handleClick, "aria-label": tooltipTitle, color: "grey", children: isFocusedMode ? _jsx(MinimizeOutlineMd, {}) : _jsx(FullSizeOutlineMd, {}) }) }), _jsx(MainActionsWrapper, { "$spacing": spacing, className: classnames, children: _jsx(MainActions, { isDisabled: disabledAction, actions: main, size: size, spacing: spacing, isRenderActionDisabled: isRenderActionDisabled }) }), (secondaryVisible || secondary) && (_jsxs(SecondaryVisibleWrapper, { "$spacing": spacing, className: classnames, children: [secondaryVisible && (_jsx(SecondaryVisibleActions, { actions: secondaryVisible, size: size, isRenderActionDisabled: isRenderActionDisabled })), secondary && (_jsx(SecondaryActions, { isDisabled: disabledAction, actions: secondary, size: size }))] })), collapsedActions.length > 0 && (_jsx(CollapsedActionsWrapper, { className: classnames, children: _jsx(SecondaryActions, { isDisabled: disabledAction, actions: collapsedActions, size: size }) }))] }) }));
19
19
  };
20
20
  export const PageActions = forwardRefWithGeneric(PageActionsInner);
@@ -1,2 +1,2 @@
1
1
  import { type SecondaryVisibleActionProps } from '../../../ActionGroup';
2
- export declare const SecondaryVisibleActions: ({ actions, size, }: SecondaryVisibleActionProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const SecondaryVisibleActions: ({ actions, size, isRenderActionDisabled, }: SecondaryVisibleActionProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { StyledMobileButton, StyledSecondaryVisibleActions } from './styles';
3
- export const SecondaryVisibleActions = ({ actions, size = 'medium', }) => {
4
- return (_jsxs(_Fragment, { children: [actions.map(({ disabledReason, isBlockingOperation, icon, name, ...restActionProps }) => {
3
+ export const SecondaryVisibleActions = ({ actions, size = 'medium', isRenderActionDisabled, }) => {
4
+ return (_jsxs(_Fragment, { children: [actions.map(({ disabledReason, isBlockingOperation, icon, name, renderAction, ...restActionProps }) => {
5
5
  return (_jsx(StyledMobileButton, { variant: "outlined", size: size, color: "grey", ...restActionProps, children: name }, name));
6
- }), _jsx(StyledSecondaryVisibleActions, { actions: actions, size: size })] }));
6
+ }), _jsx(StyledSecondaryVisibleActions, { actions: actions, size: size, isRenderActionDisabled: isRenderActionDisabled })] }));
7
7
  };
@@ -9,6 +9,12 @@ export declare const StyledMobileButton: import("../../../styled").StyledCompone
9
9
  } & Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, ""> & import("react").RefAttributes<HTMLButtonElement> & {
10
10
  theme?: import("@emotion/react").Theme | undefined;
11
11
  }, {}, {}>;
12
- export declare const StyledSecondaryVisibleActions: import("../../../styled").StyledComponent<import("../../../ActionGroup").SecondaryVisibleActionProps & {
12
+ export declare const StyledSecondaryVisibleActions: import("../../../styled").StyledComponent<{
13
+ actions: import("../../../ActionGroup").SecondaryVisibleAction[];
14
+ className?: string | undefined;
15
+ size?: import("../../../Button").ButtonSize | undefined;
16
+ } & {
17
+ isRenderActionDisabled?: boolean | undefined;
18
+ } & {
13
19
  theme?: import("@emotion/react").Theme | undefined;
14
20
  }, {}, {}>;
@@ -3,6 +3,7 @@ import { type SecondaryAction } from '../../../ActionGroup';
3
3
  import type { PageActionsProps } from '../types';
4
4
  export declare const useLogic: <TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType>({ main, secondary, secondaryVisible, withCollapseOnLaptop, }: PageActionsProps<TMainActionComponent, TSecondaryActionComponent>) => {
5
5
  disabledAction: boolean;
6
+ isRenderActionDisabled: boolean;
6
7
  buttonClassnames: string;
7
8
  isFocusedMode: boolean;
8
9
  handleClick: () => void;
@@ -2,11 +2,13 @@ import { useContext, useMemo } from 'react';
2
2
  import { useActionsState } from '../../../ActionGroup';
3
3
  import { NextFeatureFlagsContext } from '../../../ConfigProvider/NextFeatureFlagsContext';
4
4
  import { DashboardContext } from '../../../DashboardContext';
5
+ import { useViewportType } from '../../../useViewportType';
5
6
  import { cn } from '../../../utils/cn';
6
7
  import { actionsClassnames, focusModeButtonClassnames } from '../constants';
7
8
  export const useLogic = ({ main, secondary, secondaryVisible, withCollapseOnLaptop = false, }) => {
8
9
  const { showFocusModeButtonOnDesktop, showFocusModeButtonOnLaptop } = useContext(NextFeatureFlagsContext);
9
10
  const { setFocusedMode, isFocusedMode } = useContext(DashboardContext);
11
+ const { isMobile } = useViewportType();
10
12
  const { disabledAction } = useActionsState({ main, secondary });
11
13
  const buttonClassnames = useMemo(() => cn({
12
14
  [focusModeButtonClassnames.isShowOnDesktop]: showFocusModeButtonOnDesktop,
@@ -58,6 +60,7 @@ export const useLogic = ({ main, secondary, secondaryVisible, withCollapseOnLapt
58
60
  }, [withCollapseOnLaptop]);
59
61
  return {
60
62
  disabledAction,
63
+ isRenderActionDisabled: isMobile,
61
64
  buttonClassnames,
62
65
  isFocusedMode,
63
66
  handleClick,
@@ -1,5 +1,5 @@
1
1
  export * from './Accordion';
2
- export { ActionGroup, type ActionGroupProps, type MainAction, useMainActions, } from './ActionGroup';
2
+ export { ActionGroup, type ActionElementProps, type ActionGroupProps, type ActionRenderContext, type MainAction, type NestedActionRenderContext, useMainActions, } from './ActionGroup';
3
3
  export { AddressAutocomplete, type AddressAutocompleteProps, type AddressAutocompleteValue, } from './AddressAutocomplete';
4
4
  export { alertClassnames, Alert, type AlertProps, type AlertSeverity, } from './Alert';
5
5
  export { AsyncAutocomplete, type AsyncAutocompleteProps, } from './AsyncAutocomplete';
@@ -0,0 +1,9 @@
1
+ import { type ElementType } from 'react';
2
+ import type { ProcessedMainAction } from '../hooks';
3
+ export type ActionNodeProps<TMainActionComponent extends ElementType> = ProcessedMainAction<TMainActionComponent> & {
4
+ isRenderActionDisabled?: boolean;
5
+ };
6
+ /**
7
+ * Отображает одно основное действие: стандартный узел кита либо то, что вернул `renderAction`
8
+ */
9
+ export declare const ActionNode: <TMainActionComponent extends ElementType>(props: ActionNodeProps<TMainActionComponent>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionNode = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const DropdownButton_1 = require("../../../DropdownButton");
7
+ const MenuItem_1 = require("../../../MenuItem");
8
+ const Tooltip_1 = require("../../../Tooltip");
9
+ const styles_1 = require("../styles");
10
+ /**
11
+ * Отображает одно основное действие: стандартный узел кита либо то, что вернул `renderAction`
12
+ */
13
+ const ActionNode = (props) => {
14
+ const { tooltipProps, renderAction, isRenderActionDisabled = false } = props;
15
+ const { key, ...restTooltipProps } = tooltipProps;
16
+ const isRenderActionCalled = !isRenderActionDisabled && Boolean(renderAction);
17
+ // Якорь в состоянии, а не в ref: мутация ref.current не вызывает обновление, и popover на первом кадре остался бы без якоря
18
+ const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
19
+ // Лишний render при монтировании достаётся только действиям с renderAction.
20
+ const anchorRef = isRenderActionCalled && !props.isNested ? setAnchorEl : undefined;
21
+ const defaultElement = ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { ...restTooltipProps, ref: anchorRef, children: props.isNested ? ((0, jsx_runtime_1.jsx)(DropdownButton_1.DropdownButton, { ...props.buttonProps, children: props.nestedActions.map(({ key: nestedKey, text, ...nestedProps }) => ((0, jsx_runtime_1.jsx)(MenuItem_1.MenuItem, { ...nestedProps, children: text }, nestedKey))) })) : ((0, jsx_runtime_1.jsx)(styles_1.StyledButton, { ...props.buttonProps })) }));
22
+ if (isRenderActionDisabled || !props.renderAction) {
23
+ return defaultElement;
24
+ }
25
+ if (props.isNested) {
26
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: props.renderAction({ defaultElement }) });
27
+ }
28
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: props.renderAction({
29
+ defaultElement,
30
+ elementProps: props.elementProps,
31
+ anchorEl,
32
+ }) }));
33
+ };
34
+ exports.ActionNode = ActionNode;
@@ -0,0 +1 @@
1
+ export * from './ActionNode';
@@ -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("./ActionNode"), exports);
@@ -1,3 +1,3 @@
1
1
  import { type ElementType } from 'react';
2
2
  import type { MainActionsProps } from '../types';
3
- export declare const MainActions: <TMainActionComponent extends ElementType = ElementType>({ actions, isDisabled, size, }: MainActionsProps<TMainActionComponent>) => import("react/jsx-runtime").JSX.Element;
3
+ export declare const MainActions: <TMainActionComponent extends ElementType = ElementType>({ actions, isDisabled, size, isRenderActionDisabled, }: MainActionsProps<TMainActionComponent>) => import("react/jsx-runtime").JSX.Element;
@@ -2,21 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MainActions = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const react_1 = require("react");
6
- const MenuItem_1 = require("../../MenuItem");
7
- const Tooltip_1 = require("../../Tooltip");
5
+ const ActionNode_1 = require("./ActionNode");
8
6
  const hooks_1 = require("./hooks");
9
- const styles_1 = require("./styles");
10
- const MainActions = ({ actions, isDisabled, size, }) => {
7
+ const MainActions = ({ actions, isDisabled, size, isRenderActionDisabled = false, }) => {
11
8
  const processedActions = (0, hooks_1.useMainActions)({ actions, size, isDisabled });
12
- return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: processedActions.map(({ tooltipProps, isNested, buttonProps, nestedActions }) => {
13
- const { key: tooltipKey, ...restTooltipProps } = tooltipProps;
14
- if (isNested) {
15
- return ((0, react_1.createElement)(Tooltip_1.Tooltip, { ...restTooltipProps, key: tooltipKey },
16
- (0, jsx_runtime_1.jsx)(styles_1.StyledDropdownButton, { ...buttonProps, children: nestedActions.map(({ key, text, ...nestedProps }) => ((0, jsx_runtime_1.jsx)(MenuItem_1.MenuItem, { ...nestedProps, children: text }, key))) })));
17
- }
18
- return ((0, react_1.createElement)(Tooltip_1.Tooltip, { ...restTooltipProps, key: tooltipKey },
19
- (0, jsx_runtime_1.jsx)(styles_1.StyledButton, { ...buttonProps })));
20
- }) }));
9
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: processedActions.map((action) => ((0, jsx_runtime_1.jsx)(ActionNode_1.ActionNode, { isRenderActionDisabled: isRenderActionDisabled, ...action }, action.tooltipProps.key))) }));
21
10
  };
22
11
  exports.MainActions = MainActions;