@astral/ui 4.26.1 → 4.27.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 (83) hide show
  1. package/components/ConfigProvider/NextFeatureFlagsContext/NextFeatureFlagsContext.d.ts +10 -1
  2. package/components/ConfigProvider/NextFeatureFlagsContext/NextFeatureFlagsContext.js +4 -1
  3. package/components/DashboardContext/DashboardContext.d.ts +1 -0
  4. package/components/DashboardContext/DashboardContext.js +1 -0
  5. package/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.js +8 -1
  6. package/components/DashboardLayout/DashboardLayout.js +3 -5
  7. package/components/DashboardLayout/DashboardWrapper/DashboardWrapper.d.ts +6 -0
  8. package/components/DashboardLayout/DashboardWrapper/DashboardWrapper.js +10 -0
  9. package/components/DashboardLayout/DashboardWrapper/index.d.ts +1 -0
  10. package/components/DashboardLayout/DashboardWrapper/index.js +1 -0
  11. package/components/DashboardLayout/{styles.d.ts → DashboardWrapper/styles.d.ts} +3 -3
  12. package/components/DashboardLayout/{styles.js → DashboardWrapper/styles.js} +10 -7
  13. package/components/DashboardLayout/Header/styles.js +7 -3
  14. package/components/DashboardLayout/constants.d.ts +2 -1
  15. package/components/DashboardLayout/constants.js +2 -1
  16. package/components/DashboardLayoutSkeleton/DashboardLayoutSkeleton.js +1 -1
  17. package/components/DashboardSidebar/styles.js +6 -1
  18. package/components/DataGridPaginationContainer/styles.js +4 -0
  19. package/components/PageContent/styles.js +5 -0
  20. package/components/PageHeader/PageActions/PageActions.d.ts +1 -20
  21. package/components/PageHeader/PageActions/PageActions.js +10 -4
  22. package/components/PageHeader/PageActions/constants.d.ts +4 -0
  23. package/components/PageHeader/PageActions/constants.js +5 -0
  24. package/components/PageHeader/PageActions/index.d.ts +1 -0
  25. package/components/PageHeader/PageActions/styles.d.ts +9 -0
  26. package/components/PageHeader/PageActions/styles.js +17 -0
  27. package/components/PageHeader/PageActions/types.d.ts +14 -0
  28. package/components/PageHeader/PageActions/types.js +1 -0
  29. package/components/PageHeader/PageActions/useLogic/index.d.ts +1 -0
  30. package/components/PageHeader/PageActions/useLogic/index.js +1 -0
  31. package/components/PageHeader/PageActions/useLogic/useLogic.d.ts +11 -0
  32. package/components/PageHeader/PageActions/useLogic/useLogic.js +28 -0
  33. package/components/PageHeader/styles.js +4 -0
  34. package/components/PageLayoutContainer/styles.js +4 -0
  35. package/components/PageLayoutFooter/styles.js +2 -1
  36. package/components/PagePinnableAside/styles.js +6 -1
  37. package/components/constants/footer.d.ts +2 -0
  38. package/components/constants/footer.js +2 -0
  39. package/components/constants/index.d.ts +1 -0
  40. package/components/constants/index.js +1 -0
  41. package/components/useFeatureFlags/useFeatureFlags.d.ts +4 -1
  42. package/node/components/ConfigProvider/NextFeatureFlagsContext/NextFeatureFlagsContext.d.ts +10 -1
  43. package/node/components/ConfigProvider/NextFeatureFlagsContext/NextFeatureFlagsContext.js +4 -1
  44. package/node/components/DashboardContext/DashboardContext.d.ts +1 -0
  45. package/node/components/DashboardContext/DashboardContext.js +1 -0
  46. package/node/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.js +8 -1
  47. package/node/components/DashboardLayout/DashboardLayout.js +2 -4
  48. package/node/components/DashboardLayout/DashboardWrapper/DashboardWrapper.d.ts +6 -0
  49. package/node/components/DashboardLayout/DashboardWrapper/DashboardWrapper.js +14 -0
  50. package/node/components/DashboardLayout/DashboardWrapper/index.d.ts +1 -0
  51. package/node/components/DashboardLayout/DashboardWrapper/index.js +17 -0
  52. package/node/components/DashboardLayout/{styles.js → DashboardWrapper/styles.js} +10 -7
  53. package/node/components/DashboardLayout/Header/styles.js +6 -2
  54. package/node/components/DashboardLayout/constants.d.ts +2 -1
  55. package/node/components/DashboardLayout/constants.js +3 -2
  56. package/node/components/DashboardLayoutSkeleton/DashboardLayoutSkeleton.js +1 -1
  57. package/node/components/DashboardSidebar/styles.js +14 -9
  58. package/node/components/DataGridPaginationContainer/styles.js +4 -0
  59. package/node/components/PageContent/styles.js +5 -0
  60. package/node/components/PageHeader/PageActions/PageActions.d.ts +1 -20
  61. package/node/components/PageHeader/PageActions/PageActions.js +9 -3
  62. package/node/components/PageHeader/PageActions/constants.d.ts +4 -0
  63. package/node/components/PageHeader/PageActions/constants.js +8 -0
  64. package/node/components/PageHeader/PageActions/index.d.ts +1 -0
  65. package/node/components/PageHeader/PageActions/styles.d.ts +9 -0
  66. package/node/components/PageHeader/PageActions/styles.js +18 -1
  67. package/node/components/PageHeader/PageActions/types.d.ts +14 -0
  68. package/node/components/PageHeader/PageActions/types.js +2 -0
  69. package/node/components/PageHeader/PageActions/useLogic/index.d.ts +1 -0
  70. package/node/components/PageHeader/PageActions/useLogic/index.js +17 -0
  71. package/node/components/PageHeader/PageActions/useLogic/useLogic.d.ts +11 -0
  72. package/node/components/PageHeader/PageActions/useLogic/useLogic.js +32 -0
  73. package/node/components/PageHeader/styles.js +4 -0
  74. package/node/components/PageLayoutContainer/styles.js +4 -0
  75. package/node/components/PageLayoutFooter/styles.js +2 -1
  76. package/node/components/PagePinnableAside/styles.js +8 -3
  77. package/node/components/constants/footer.d.ts +2 -0
  78. package/node/components/constants/footer.js +5 -0
  79. package/node/components/constants/index.d.ts +1 -0
  80. package/node/components/constants/index.js +1 -0
  81. package/node/components/useFeatureFlags/useFeatureFlags.d.ts +4 -1
  82. package/package.json +1 -1
  83. /package/node/components/DashboardLayout/{styles.d.ts → DashboardWrapper/styles.d.ts} +0 -0
@@ -1,5 +1,14 @@
1
1
  /// <reference types="react" />
2
- type FeatureFlags = {};
2
+ type FeatureFlags = {
3
+ /**
4
+ * Флаг отображения кнопки focused mode на маленьких экранах.
5
+ */
6
+ showFocusModeButtonOnLaptop?: boolean;
7
+ /**
8
+ * Флаг отображения кнопки focused mode на больших экранах.
9
+ */
10
+ showFocusModeButtonOnDesktop?: boolean;
11
+ };
3
12
  export type NextFeatureFlagsContextProps = FeatureFlags;
4
13
  /**
5
14
  * Контекст для хранения и передачи фича-флагов в приложении.
@@ -3,4 +3,7 @@ import { createContext } from 'react';
3
3
  * Контекст для хранения и передачи фича-флагов в приложении.
4
4
  * Фича-флаги позволяют управлять функциональностью компонентов на уровне конфигурации.
5
5
  */
6
- export const NextFeatureFlagsContext = createContext({});
6
+ export const NextFeatureFlagsContext = createContext({
7
+ showFocusModeButtonOnDesktop: false,
8
+ showFocusModeButtonOnLaptop: false,
9
+ });
@@ -5,5 +5,6 @@ export type DashboardContextProps = {
5
5
  alertHeight: number;
6
6
  isLoading: boolean;
7
7
  hasMenuOrganizationRef: RefObject<boolean | null>;
8
+ setFocusedMode: (isFocusedMode: boolean) => void;
8
9
  };
9
10
  export declare const DashboardContext: import("react").Context<DashboardContextProps>;
@@ -4,4 +4,5 @@ export const DashboardContext = createContext({
4
4
  alertHeight: 0,
5
5
  isLoading: false,
6
6
  hasMenuOrganizationRef: createRef(),
7
+ setFocusedMode: () => undefined,
7
8
  });
@@ -4,7 +4,13 @@ import { DashboardContext, } from '../DashboardContext';
4
4
  export const DashboardContextProvider = ({ children, isFocusedMode, isLoading, }) => {
5
5
  const [alertElement, setAlertElement] = useState(null);
6
6
  const [alertHeight, setAlertHeight] = useState(0);
7
+ const [isFocusedModeInternal, setFocusedMode] = useState(isFocusedMode);
7
8
  const hasMenuOrganizationRef = useRef(false);
9
+ useEffect(() => {
10
+ if (isFocusedMode !== isFocusedModeInternal) {
11
+ setFocusedMode(isFocusedMode);
12
+ }
13
+ }, [isFocusedMode]);
8
14
  useEffect(() => {
9
15
  if (!alertElement) {
10
16
  setAlertHeight(0);
@@ -20,10 +26,11 @@ export const DashboardContextProvider = ({ children, isFocusedMode, isLoading, }
20
26
  return () => resizeObserver.disconnect();
21
27
  }, [alertElement]);
22
28
  return (_jsx(DashboardContext.Provider, { value: {
23
- isFocusedMode,
29
+ isFocusedMode: isFocusedModeInternal,
24
30
  setAlertElement,
25
31
  alertHeight,
26
32
  isLoading,
27
33
  hasMenuOrganizationRef,
34
+ setFocusedMode,
28
35
  }, children: children }));
29
36
  };
@@ -1,16 +1,14 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { DashboardContextProvider } from '../DashboardContext';
3
3
  import { DashboardSidebar } from '../DashboardSidebar';
4
- import { DashboardSidebarProvider } from '../DashboardSidebarProvider';
5
- import { dashboardLayoutClassnames } from './constants';
4
+ import { DashboardWrapper } from './DashboardWrapper';
6
5
  import { Header } from './Header';
7
6
  import { Main } from './Main';
8
- import { DecorativeHeaderBackground, LayoutContent, Wrapper } from './styles';
9
7
  /**
10
8
  * Общий Layout приложения
11
9
  */
12
10
  export const DashboardLayout = ({ children, isFocusedMode = false, isLoading = false, }) => {
13
- return (_jsx(DashboardContextProvider, { isFocusedMode: isFocusedMode, isLoading: isLoading, children: _jsx(DashboardSidebarProvider, { isFocusedMode: isFocusedMode, children: _jsxs(Wrapper, { className: dashboardLayoutClassnames.root, children: [_jsx(DecorativeHeaderBackground, { role: "presentation", "$isFocusedMode": isFocusedMode }), _jsx(LayoutContent, { "$isFocusedMode": isFocusedMode, children: children })] }) }) }));
11
+ return (_jsx(DashboardContextProvider, { isFocusedMode: isFocusedMode, isLoading: isLoading, children: _jsx(DashboardWrapper, { children: children }) }));
14
12
  };
15
13
  DashboardLayout.Header = Header;
16
14
  DashboardLayout.Sidebar = DashboardSidebar;
@@ -0,0 +1,6 @@
1
+ import { type ReactNode } from 'react';
2
+ type Props = {
3
+ children: ReactNode;
4
+ };
5
+ export declare const DashboardWrapper: ({ children }: Props) => import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useContext } from 'react';
3
+ import { DashboardContext } from '../../DashboardContext';
4
+ import { DashboardSidebarProvider } from '../../DashboardSidebarProvider';
5
+ import { dashboardLayoutClassnames } from '../constants';
6
+ import { DecorativeHeaderBackground, LayoutContent, Wrapper } from './styles';
7
+ export const DashboardWrapper = ({ children }) => {
8
+ const { isFocusedMode } = useContext(DashboardContext);
9
+ return (_jsx(DashboardSidebarProvider, { isFocusedMode: isFocusedMode, children: _jsxs(Wrapper, { className: dashboardLayoutClassnames.root, children: [_jsx(DecorativeHeaderBackground, { role: "presentation", "$isFocusedMode": isFocusedMode }), _jsx(LayoutContent, { "$isFocusedMode": isFocusedMode, children: children })] }) }));
10
+ };
@@ -0,0 +1 @@
1
+ export * from './DashboardWrapper';
@@ -0,0 +1 @@
1
+ export * from './DashboardWrapper';
@@ -1,15 +1,15 @@
1
1
  /// <reference types="react" />
2
- export declare const Wrapper: import("../styled").StyledComponent<{
2
+ export declare const Wrapper: import("../../styled").StyledComponent<{
3
3
  theme?: import("@emotion/react").Theme | undefined;
4
4
  as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
5
5
  }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
6
- export declare const DecorativeHeaderBackground: import("../styled").StyledComponent<{
6
+ export declare const DecorativeHeaderBackground: import("../../styled").StyledComponent<{
7
7
  theme?: import("@emotion/react").Theme | undefined;
8
8
  as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
9
9
  } & {
10
10
  $isFocusedMode: boolean;
11
11
  }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
12
- export declare const LayoutContent: import("../styled").StyledComponent<{
12
+ export declare const LayoutContent: import("../../styled").StyledComponent<{
13
13
  theme?: import("@emotion/react").Theme | undefined;
14
14
  as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
15
15
  } & {
@@ -1,6 +1,6 @@
1
- import { dashboardSidebarClassnames } from '../DashboardSidebar/constants';
2
- import { styled } from '../styled';
3
- import { HEADER_HEIGHT } from './constants';
1
+ import { dashboardSidebarClassnames } from '../../DashboardSidebar/constants';
2
+ import { styled } from '../../styled';
3
+ import { HEADER_HEIGHT_DESKTOP, HEADER_HEIGHT_LAPTOP } from '../constants';
4
4
  export const Wrapper = styled('div') `
5
5
  display: flex;
6
6
  justify-content: center;
@@ -9,9 +9,7 @@ export const Wrapper = styled('div') `
9
9
 
10
10
  background-color: ${({ theme }) => theme.palette.background.body};
11
11
  `;
12
- export const DecorativeHeaderBackground = styled('div', {
13
- shouldForwardProp: (prop) => !['$isFocusedMode'].includes(prop),
14
- }) `
12
+ export const DecorativeHeaderBackground = styled.div `
15
13
  position: absolute;
16
14
 
17
15
  /* Header находится над декоративным элементом */
@@ -19,7 +17,7 @@ export const DecorativeHeaderBackground = styled('div', {
19
17
  left: 0;
20
18
 
21
19
  width: 100%;
22
- height: ${({ $isFocusedMode }) => ($isFocusedMode ? 0 : HEADER_HEIGHT)};
20
+ height: ${({ $isFocusedMode }) => ($isFocusedMode ? 0 : HEADER_HEIGHT_DESKTOP)};
23
21
 
24
22
  background-color: ${({ theme }) => theme.palette.background.default};
25
23
  border-bottom: 1px solid ${({ theme }) => theme.palette.grey[300]};
@@ -29,6 +27,11 @@ export const DecorativeHeaderBackground = styled('div', {
29
27
  duration: theme.transitions.duration.complex,
30
28
  });
31
29
  }};
30
+
31
+ ${({ theme }) => theme.breakpoints.down('lg')} {
32
+ height: ${({ $isFocusedMode }) => ($isFocusedMode ? 0 : HEADER_HEIGHT_LAPTOP)}
33
+ }
34
+
32
35
  ${({ theme }) => theme.breakpoints.down('sm')} {
33
36
  display: none;
34
37
  }
@@ -4,7 +4,7 @@ import { IconButton } from '../../IconButton';
4
4
  import { menuOrganizationClassnames } from '../../MenuOrganization/constants';
5
5
  import { MOBILE_BUTTON_HEIGHT } from '../../MenuOrganization/OrganizationButton/constants';
6
6
  import { styled } from '../../styled';
7
- import { dashboardLayoutClassnames, HEADER_HEIGHT, HEADER_HEIGHT_MOBILE, } from '../constants';
7
+ import { dashboardLayoutClassnames, HEADER_HEIGHT_DESKTOP, HEADER_HEIGHT_LAPTOP, HEADER_HEIGHT_MOBILE, } from '../constants';
8
8
  import { dashboardLayoutHeaderClassnames } from './constants';
9
9
  export const HeaderRoot = styled('header', {
10
10
  shouldForwardProp: (prop) => !['$isFocusedMode'].includes(prop),
@@ -18,8 +18,8 @@ export const HeaderRoot = styled('header', {
18
18
  justify-content: space-between;
19
19
 
20
20
  width: 100%;
21
- height: ${HEADER_HEIGHT};
22
- margin-top: ${({ $isFocusedMode }) => $isFocusedMode ? `-${HEADER_HEIGHT}` : 0};
21
+ height: ${HEADER_HEIGHT_DESKTOP};
22
+ margin-top: ${({ $isFocusedMode }) => $isFocusedMode ? `-${HEADER_HEIGHT_DESKTOP}` : 0};
23
23
  margin-bottom: ${({ theme }) => theme.spacing(4)};
24
24
 
25
25
  transition: ${({ theme }) => {
@@ -28,6 +28,10 @@ export const HeaderRoot = styled('header', {
28
28
  });
29
29
  }};
30
30
 
31
+ ${({ theme }) => theme.breakpoints.down('lg')} {
32
+ height: ${HEADER_HEIGHT_LAPTOP};
33
+ }
34
+
31
35
  ${({ theme }) => theme.breakpoints.down('sm')} {
32
36
  grid-row: 2;
33
37
  justify-content: flex-start;
@@ -1,4 +1,5 @@
1
- export declare const HEADER_HEIGHT = "60px";
1
+ export declare const HEADER_HEIGHT_DESKTOP = "60px";
2
+ export declare const HEADER_HEIGHT_LAPTOP = "56px";
2
3
  export declare const HEADER_HEIGHT_MOBILE = "48px";
3
4
  export declare const dashboardLayoutClassnames: {
4
5
  root: string;
@@ -1,5 +1,6 @@
1
1
  import { createUIKitClassname } from '../utils/createUIKitClassname';
2
- export const HEADER_HEIGHT = '60px';
2
+ export const HEADER_HEIGHT_DESKTOP = '60px';
3
+ export const HEADER_HEIGHT_LAPTOP = '56px';
3
4
  export const HEADER_HEIGHT_MOBILE = '48px';
4
5
  export const dashboardLayoutClassnames = {
5
6
  root: createUIKitClassname('dashboard-layout'),
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { dashboardLayoutClassnames } from '../DashboardLayout/constants';
3
3
  import { DashboardLayout } from '../DashboardLayout/DashboardLayout';
4
+ import { DecorativeHeaderBackground, LayoutContent, Wrapper, } from '../DashboardLayout/DashboardWrapper/styles';
4
5
  import { Header } from '../DashboardLayout/Header';
5
- import { DecorativeHeaderBackground, LayoutContent, Wrapper, } from '../DashboardLayout/styles';
6
6
  import { DashboardSidebarSkeleton } from '../DashboardSidebarSkeleton';
7
7
  import { MenuOrganizationSkeleton } from '../MenuOrganization';
8
8
  import { LoadingPlaceholder } from '../placeholders/LoadingPlaceholder';
@@ -1,3 +1,4 @@
1
+ import { FOOTER_DESKTOP_HEIGHT, FOOTER_LAPTOP_HEIGHT } from '../constants';
1
2
  import { HEADER_HEIGHT_MOBILE } from '../DashboardLayout/constants';
2
3
  import { menuOrganizationClassnames } from '../MenuOrganization/constants';
3
4
  import { MOBILE_BUTTON_HEIGHT } from '../MenuOrganization/OrganizationButton';
@@ -122,7 +123,7 @@ export const Footer = styled.footer `
122
123
  flex-shrink: 0;
123
124
 
124
125
  box-sizing: content-box;
125
- height: 64px;
126
+ height: ${FOOTER_DESKTOP_HEIGHT};
126
127
  margin-top: auto;
127
128
 
128
129
  background-color: ${({ theme }) => theme.palette.background.default};
@@ -137,4 +138,8 @@ export const Footer = styled.footer `
137
138
  ${({ theme }) => theme.breakpoints.down('sm')} {
138
139
  display: none;
139
140
  }
141
+
142
+ ${({ theme }) => theme.breakpoints.down('lg')} {
143
+ height: ${FOOTER_LAPTOP_HEIGHT};
144
+ }
140
145
  `;
@@ -24,6 +24,10 @@ export const PaginationWrapper = styled.div `
24
24
  margin: 0 ${({ theme }) => theme.spacing(2)};
25
25
  padding-top: ${({ theme }) => theme.spacing(4)};
26
26
 
27
+ ${({ theme }) => theme.breakpoints.down('lg')} {
28
+ padding-top: ${({ theme }) => theme.spacing(2)};
29
+ }
30
+
27
31
  ${({ theme }) => theme.breakpoints.down('sm')} {
28
32
  height: 56px;
29
33
  padding: ${({ theme }) => theme.spacing(3, 4)};
@@ -59,6 +59,11 @@ export const Content = styled.div `
59
59
 
60
60
  padding: ${({ theme, $hasAside }) => getPaddingContent(theme, $hasAside)};
61
61
 
62
+ ${({ theme }) => theme.breakpoints.down('lg')} {
63
+ padding-right: ${({ theme }) => theme.spacing(4)};
64
+ padding-left: ${({ theme }) => theme.spacing(4)};
65
+ }
66
+
62
67
  ${({ theme }) => theme.breakpoints.down('sm')} {
63
68
  scrollbar-gutter: unset;
64
69
 
@@ -1,25 +1,6 @@
1
1
  import { type ElementType } from 'react';
2
- import { type ActionGroupProps } from '../../ActionGroup';
3
- import { type ButtonSize } from '../../Button';
4
- export type PageActionsProps<TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType> = ActionGroupProps<TMainActionComponent, TSecondaryActionComponent> & {
5
- /**
6
- * Если true, отображается skeleton
7
- */
8
- isLoading?: boolean;
9
- size?: ButtonSize;
10
- /**
11
- * Отступ между действиями
12
- */
13
- spacing?: number;
14
- };
15
- export declare const PageActions: <TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType>(props: ActionGroupProps<TMainActionComponent, TSecondaryActionComponent> & {
16
- /**
17
- * Если true, отображается skeleton
18
- */
2
+ export declare const PageActions: <TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType>(props: import("../..").ActionGroupProps<TMainActionComponent, TSecondaryActionComponent> & {
19
3
  isLoading?: boolean | undefined;
20
4
  size?: "large" | "medium" | undefined;
21
- /**
22
- * Отступ между действиями
23
- */
24
5
  spacing?: number | undefined;
25
6
  } & import("react").RefAttributes<HTMLDivElement>) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null;
@@ -1,18 +1,24 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useActionsState } from '../../ActionGroup';
2
+ import { FullSizeOutlineMd } from '../../../icons/FullSizeOutlineMd';
3
+ import { MinimizeOutlineMd } from '../../../icons/MinimizeOutlineMd';
3
4
  import { forwardRefWithGeneric } from '../../forwardRefWithGeneric';
5
+ import { Tooltip } from '../../Tooltip';
4
6
  import { MainActions } from './MainActions';
5
7
  import { PageActionSkeleton } from './PageActionSkeleton';
6
8
  import { SecondaryActions } from './SecondaryActions';
7
9
  import { SecondaryVisibleActions } from './SecondaryVisibleActions';
8
- import { ActionWrapper, SecondaryWrapper, Wrapper } from './styles';
10
+ import { ActionWrapper, FocusModeButton, SecondaryWrapper, Wrapper, } from './styles';
11
+ import { useLogic } from './useLogic';
9
12
  const PageActionsInner = (props, ref) => {
10
13
  const { secondary, secondaryVisible, main, className, isLoading, size = 'medium', spacing = 2, } = props;
11
- const { disabledAction } = useActionsState({ main, secondary });
14
+ const { disabledAction, buttonClassnames, isFocusedMode, handleClick, tooltipTitle, } = useLogic({
15
+ main,
16
+ secondary,
17
+ });
12
18
  const renderSecondaryActions = () => (_jsxs(SecondaryWrapper, { "$spacing": spacing, children: [secondaryVisible && (_jsx(SecondaryVisibleActions, { actions: secondaryVisible, size: size })), secondary && (_jsx(SecondaryActions, { isDisabled: disabledAction, actions: secondary, size: size }))] }));
13
19
  if (isLoading) {
14
20
  return (_jsx(Wrapper, { children: _jsx(PageActionSkeleton, { size: size }) }));
15
21
  }
16
- return (_jsx(Wrapper, { className: className, ref: ref, children: _jsxs(ActionWrapper, { "$spacing": spacing, children: [_jsx(MainActions, { isDisabled: disabledAction, actions: main, size: size, spacing: spacing }), renderSecondaryActions()] }) }));
22
+ 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(MainActions, { isDisabled: disabledAction, actions: main, size: size, spacing: spacing }), renderSecondaryActions()] }) }));
17
23
  };
18
24
  export const PageActions = forwardRefWithGeneric(PageActionsInner);
@@ -0,0 +1,4 @@
1
+ export declare const focusModeButtonClassnames: {
2
+ isShowOnDesktop: string;
3
+ isShowOnLaptop: string;
4
+ };
@@ -0,0 +1,5 @@
1
+ import { createUIKitClassname } from '../../utils/createUIKitClassname';
2
+ export const focusModeButtonClassnames = {
3
+ isShowOnDesktop: createUIKitClassname('focus-mode-button__show-desktop'),
4
+ isShowOnLaptop: createUIKitClassname('focus-mode-button__show-laptop'),
5
+ };
@@ -1,5 +1,6 @@
1
1
  export * from './MainActions';
2
2
  export * from './PageActionSkeleton';
3
3
  export * from './PageActions';
4
+ export type { PageActionsProps } from './types';
4
5
  export * from './SecondaryActions';
5
6
  export * from './SecondaryVisibleActions';
@@ -15,3 +15,12 @@ export declare const ActionWrapper: import("../../styled").StyledComponent<{
15
15
  } & {
16
16
  $spacing: number;
17
17
  }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
18
+ export declare const FocusModeButton: import("../../styled").StyledComponent<Omit<import("../..").WithoutEmotionSpecific<import("@mui/material").ButtonProps>, "color" | "component" | "variant" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple"> & {
19
+ variant?: "light" | "link" | "text" | "contained" | "outlined" | undefined;
20
+ loading?: boolean | undefined;
21
+ color?: "primary" | "success" | "warning" | "error" | "grey" | undefined;
22
+ component?: import("react").ElementType | undefined;
23
+ selected?: boolean | undefined;
24
+ } & Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, ""> & import("react").RefAttributes<HTMLButtonElement> & {
25
+ theme?: import("@emotion/react").Theme | undefined;
26
+ }, {}, {}>;
@@ -1,4 +1,6 @@
1
+ import { IconButton } from '../../IconButton';
1
2
  import { styled } from '../../styled';
3
+ import { focusModeButtonClassnames } from './constants';
2
4
  export const Wrapper = styled.div `
3
5
  display: flex;
4
6
  grid-column: 3;
@@ -27,3 +29,18 @@ export const ActionWrapper = styled.div `
27
29
  gap: ${({ theme }) => theme.spacing(2)};
28
30
  }
29
31
  `;
32
+ export const FocusModeButton = styled(IconButton) `
33
+ display: none;
34
+
35
+ ${({ theme }) => theme.breakpoints.down('lg')} {
36
+ &.${focusModeButtonClassnames.isShowOnLaptop} {
37
+ display: inline-flex;
38
+ }
39
+ }
40
+
41
+ ${({ theme }) => theme.breakpoints.up('lg')} {
42
+ &.${focusModeButtonClassnames.isShowOnDesktop} {
43
+ display: inline-flex;
44
+ }
45
+ }
46
+ `;
@@ -0,0 +1,14 @@
1
+ import type { ElementType } from 'react';
2
+ import type { ActionGroupProps } from '../../ActionGroup';
3
+ import type { ButtonSize } from '../../Button';
4
+ export type PageActionsProps<TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType> = ActionGroupProps<TMainActionComponent, TSecondaryActionComponent> & {
5
+ /**
6
+ * Если true, отображается skeleton
7
+ */
8
+ isLoading?: boolean;
9
+ size?: ButtonSize;
10
+ /**
11
+ * Отступ между действиями
12
+ */
13
+ spacing?: number;
14
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export * from './useLogic';
@@ -0,0 +1 @@
1
+ export * from './useLogic';
@@ -0,0 +1,11 @@
1
+ import { type ElementType } from 'react';
2
+ import type { PageActionsProps } from '../types';
3
+ type UseLogicParams<TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType> = Pick<PageActionsProps<TMainActionComponent, TSecondaryActionComponent>, 'main' | 'secondary'>;
4
+ export declare const useLogic: <TMainActionComponent extends ElementType = ElementType, TSecondaryActionComponent extends ElementType = ElementType>({ main, secondary, }: UseLogicParams<TMainActionComponent, TSecondaryActionComponent>) => {
5
+ disabledAction: boolean;
6
+ buttonClassnames: string;
7
+ isFocusedMode: boolean;
8
+ handleClick: () => void;
9
+ tooltipTitle: string;
10
+ };
11
+ export {};
@@ -0,0 +1,28 @@
1
+ import { useContext, useMemo } from 'react';
2
+ import { useActionsState } from '../../../ActionGroup';
3
+ import { NextFeatureFlagsContext } from '../../../ConfigProvider/NextFeatureFlagsContext';
4
+ import { DashboardContext } from '../../../DashboardContext';
5
+ import { classNames } from '../../../utils/classNames';
6
+ import { focusModeButtonClassnames } from '../constants';
7
+ export const useLogic = ({ main, secondary, }) => {
8
+ const { showFocusModeButtonOnDesktop, showFocusModeButtonOnLaptop } = useContext(NextFeatureFlagsContext);
9
+ const { setFocusedMode, isFocusedMode } = useContext(DashboardContext);
10
+ const { disabledAction } = useActionsState({ main, secondary });
11
+ const buttonClassnames = useMemo(() => classNames({
12
+ [focusModeButtonClassnames.isShowOnDesktop]: showFocusModeButtonOnDesktop,
13
+ [focusModeButtonClassnames.isShowOnLaptop]: showFocusModeButtonOnLaptop,
14
+ }), [showFocusModeButtonOnDesktop, showFocusModeButtonOnLaptop]);
15
+ const handleClick = () => {
16
+ setFocusedMode(!isFocusedMode);
17
+ };
18
+ const tooltipTitle = isFocusedMode
19
+ ? 'Свернуть и вернуть шапку сервиса'
20
+ : 'Раскрыть на весь экран';
21
+ return {
22
+ disabledAction,
23
+ buttonClassnames,
24
+ isFocusedMode,
25
+ handleClick,
26
+ tooltipTitle,
27
+ };
28
+ };
@@ -10,6 +10,10 @@ export const Wrapper = styled.header `
10
10
 
11
11
  padding: ${({ theme }) => theme.spacing(0, 6)};
12
12
 
13
+ ${({ theme }) => theme.breakpoints.down('lg')} {
14
+ padding: ${({ theme }) => theme.spacing(0, 4)};
15
+ }
16
+
13
17
  ${({ theme }) => theme.breakpoints.down('sm')} {
14
18
  display: block;
15
19
 
@@ -13,6 +13,10 @@ export const Wrapper = styled.div `
13
13
 
14
14
  background-color: ${({ theme }) => theme.palette.common.white};
15
15
 
16
+ ${({ theme }) => theme.breakpoints.down('lg')} {
17
+ grid-row-gap: 0;
18
+ }
19
+
16
20
  ${({ theme }) => theme.breakpoints.down('sm')} {
17
21
  scroll-behavior: smooth;
18
22
 
@@ -1,3 +1,4 @@
1
+ import { FOOTER_DESKTOP_HEIGHT } from '../constants';
1
2
  import { styled } from '../styled';
2
3
  export const Wrapper = styled.footer `
3
4
  display: flex;
@@ -5,7 +6,7 @@ export const Wrapper = styled.footer `
5
6
  align-items: center;
6
7
  justify-content: flex-end;
7
8
 
8
- min-height: 64px;
9
+ min-height: ${FOOTER_DESKTOP_HEIGHT};
9
10
  padding: ${({ theme }) => theme.spacing(0, 6)};
10
11
 
11
12
  background-color: ${({ theme }) => theme.palette.background.default};
@@ -1,3 +1,4 @@
1
+ import { FOOTER_DESKTOP_HEIGHT, FOOTER_LAPTOP_HEIGHT } from '../constants';
1
2
  import { PAGE_ASIDE_WIDTH } from '../PageAside';
2
3
  import { css, styled } from '../styled';
3
4
  import { pinnableAsideClassnames } from './constants';
@@ -120,7 +121,7 @@ export const Footer = styled.footer `
120
121
  flex-shrink: 0;
121
122
 
122
123
  box-sizing: content-box;
123
- height: 64px;
124
+ height: ${FOOTER_DESKTOP_HEIGHT};
124
125
  margin-top: auto;
125
126
 
126
127
  background-color: ${({ theme }) => theme.palette.background.default};
@@ -129,4 +130,8 @@ export const Footer = styled.footer `
129
130
  ${({ theme }) => theme.breakpoints.down('sm')} {
130
131
  display: none;
131
132
  }
133
+
134
+ ${({ theme }) => theme.breakpoints.down('lg')} {
135
+ height: ${FOOTER_LAPTOP_HEIGHT};
136
+ }
132
137
  `;
@@ -0,0 +1,2 @@
1
+ export declare const FOOTER_DESKTOP_HEIGHT = "64px";
2
+ export declare const FOOTER_LAPTOP_HEIGHT = "56px";
@@ -0,0 +1,2 @@
1
+ export const FOOTER_DESKTOP_HEIGHT = '64px';
2
+ export const FOOTER_LAPTOP_HEIGHT = '56px';
@@ -1,2 +1,3 @@
1
1
  export * from './date';
2
2
  export * from './scrollbar';
3
+ export * from './footer';
@@ -1,2 +1,3 @@
1
1
  export * from './date';
2
2
  export * from './scrollbar';
3
+ export * from './footer';
@@ -17,5 +17,8 @@ type UseFeatureFlagsParams<TFlag extends keyof NextFeatureFlagsContextProps> = {
17
17
  * @param componentName - Название компонента, для которого нужно получить флаги.
18
18
  * @param localFlags - Локальные флаги, переданные через пропсы.
19
19
  */
20
- export declare const useFeatureFlags: <TFlag extends never>({ localFlags, }: UseFeatureFlagsParams<TFlag>) => {};
20
+ export declare const useFeatureFlags: <TFlag extends keyof {
21
+ showFocusModeButtonOnLaptop?: boolean | undefined;
22
+ showFocusModeButtonOnDesktop?: boolean | undefined;
23
+ }>({ localFlags, }: UseFeatureFlagsParams<TFlag>) => {};
21
24
  export {};
@@ -1,5 +1,14 @@
1
1
  /// <reference types="react" />
2
- type FeatureFlags = {};
2
+ type FeatureFlags = {
3
+ /**
4
+ * Флаг отображения кнопки focused mode на маленьких экранах.
5
+ */
6
+ showFocusModeButtonOnLaptop?: boolean;
7
+ /**
8
+ * Флаг отображения кнопки focused mode на больших экранах.
9
+ */
10
+ showFocusModeButtonOnDesktop?: boolean;
11
+ };
3
12
  export type NextFeatureFlagsContextProps = FeatureFlags;
4
13
  /**
5
14
  * Контекст для хранения и передачи фича-флагов в приложении.
@@ -6,4 +6,7 @@ const react_1 = require("react");
6
6
  * Контекст для хранения и передачи фича-флагов в приложении.
7
7
  * Фича-флаги позволяют управлять функциональностью компонентов на уровне конфигурации.
8
8
  */
9
- exports.NextFeatureFlagsContext = (0, react_1.createContext)({});
9
+ exports.NextFeatureFlagsContext = (0, react_1.createContext)({
10
+ showFocusModeButtonOnDesktop: false,
11
+ showFocusModeButtonOnLaptop: false,
12
+ });
@@ -5,5 +5,6 @@ export type DashboardContextProps = {
5
5
  alertHeight: number;
6
6
  isLoading: boolean;
7
7
  hasMenuOrganizationRef: RefObject<boolean | null>;
8
+ setFocusedMode: (isFocusedMode: boolean) => void;
8
9
  };
9
10
  export declare const DashboardContext: import("react").Context<DashboardContextProps>;
@@ -7,4 +7,5 @@ exports.DashboardContext = (0, react_1.createContext)({
7
7
  alertHeight: 0,
8
8
  isLoading: false,
9
9
  hasMenuOrganizationRef: (0, react_1.createRef)(),
10
+ setFocusedMode: () => undefined,
10
11
  });