@gravity-ui/navigation 2.16.0 → 2.17.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 (36) hide show
  1. package/README.md +4 -73
  2. package/build/cjs/AsideHeader.js +1 -1
  3. package/build/cjs/Drawer.js +121 -7
  4. package/build/cjs/Drawer.js.map +1 -1
  5. package/build/cjs/{FooterItem-e11d85c6.js → FooterItem-2c6eba14.js} +1 -1
  6. package/build/cjs/{FooterItem-e11d85c6.js.map → FooterItem-2c6eba14.js.map} +1 -1
  7. package/build/cjs/{HotkeysPanel-c6e4a0d9.js → HotkeysPanel-61ea3f99.js} +1 -1
  8. package/build/cjs/{HotkeysPanel-c6e4a0d9.js.map → HotkeysPanel-61ea3f99.js.map} +1 -1
  9. package/build/cjs/{PageLayoutAside-3fd5e2be.js → PageLayoutAside-b7365f95.js} +1 -1
  10. package/build/cjs/{PageLayoutAside-3fd5e2be.js.map → PageLayoutAside-b7365f95.js.map} +1 -1
  11. package/build/cjs/PageLayoutAside.js +1 -1
  12. package/build/cjs/components/Drawer/Drawer.d.ts +22 -2
  13. package/build/cjs/components/Drawer/index.d.ts +2 -0
  14. package/build/cjs/components/Drawer/utils.d.ts +29 -0
  15. package/build/cjs/components/index.d.ts +1 -1
  16. package/build/cjs/index.js +7 -7
  17. package/build/cjs/index4.js +1 -1
  18. package/build/cjs/index6.js +1 -1
  19. package/build/esm/AsideHeader.js +1 -1
  20. package/build/esm/Drawer.js +104 -8
  21. package/build/esm/Drawer.js.map +1 -1
  22. package/build/esm/{FooterItem-095251e4.js → FooterItem-4c4f8922.js} +1 -1
  23. package/build/esm/{FooterItem-095251e4.js.map → FooterItem-4c4f8922.js.map} +1 -1
  24. package/build/esm/{HotkeysPanel-a46d3bf8.js → HotkeysPanel-4decc57f.js} +1 -1
  25. package/build/esm/{HotkeysPanel-a46d3bf8.js.map → HotkeysPanel-4decc57f.js.map} +1 -1
  26. package/build/esm/{PageLayoutAside-1a3b5dcf.js → PageLayoutAside-10fd6371.js} +1 -1
  27. package/build/esm/{PageLayoutAside-1a3b5dcf.js.map → PageLayoutAside-10fd6371.js.map} +1 -1
  28. package/build/esm/PageLayoutAside.js +1 -1
  29. package/build/esm/components/Drawer/Drawer.d.ts +22 -2
  30. package/build/esm/components/Drawer/index.d.ts +2 -0
  31. package/build/esm/components/Drawer/utils.d.ts +29 -0
  32. package/build/esm/components/index.d.ts +1 -1
  33. package/build/esm/index.js +6 -6
  34. package/build/esm/index4.js +1 -1
  35. package/build/esm/index6.js +1 -1
  36. package/package.json +1 -1
package/README.md CHANGED
@@ -13,94 +13,25 @@ npm install @gravity-ui/navigation
13
13
  Ensure that peer dependencies are installed in your project
14
14
 
15
15
  ```bash
16
- npm install --dev @gravity-ui/uikit@^3.0.2 @bem-react/classname@1.6.0 react@^16.0.0
16
+ npm install --dev @gravity-ui/uikit@^6.15.0 @gravity-ui/icons@2.2.0 @gravity-ui/components@3.0.0 @bem-react/classname@1.6.0 react@^18.0.0 react-dom@18.0.0
17
17
  ```
18
18
 
19
19
  ## Components
20
20
 
21
- - AsideHeader
21
+ - [AsideHeader](/src/components/AsideHeader/README.md)
22
22
  - MobileHeader
23
23
  - FooterItem
24
24
  - MobileHeaderFooterItem
25
- - Drawer
25
+ - [Drawer](/src/components/Drawer/README.md)
26
26
  - DrawerItem
27
27
  - PageLayout
28
28
  - PageLayoutAside
29
29
  - AsideFallback
30
- - Logo
30
+ - [Logo](/src/components/Logo/Readme.md)
31
31
  - MobileLogo
32
32
  - Footer
33
33
  - MobileFooter
34
34
 
35
- ## Optimization
36
-
37
- If your app content needs to be rendered faster than by passing it throw `AsideHeader` props,
38
- you may need to switch usage of `AsideHeader` to advanced style with `PageLayout` like this:
39
-
40
- ```diff
41
- --- Main.tsx
42
- +++ Main.tsx
43
- -import {AsideHeader} from './AsideHeader'
44
- +import {PageLayout, AsideFallback} from '@gravity-ui/navigation';
45
- +const Aside = React.lazy(() =>
46
- + import('./Aside').then(({Aside}) => ({ default: Aside }))
47
- +);
48
-
49
- - <AsideHeader renderContent={renderContent} {...restProps} />
50
- + <PageLayout>
51
- + <Suspense fallback={<AsideFallback />}>
52
- + <Aside />
53
- + </Suspense>
54
- +
55
- + <PageLayout.Content>
56
- + <ContentExample />
57
- + </PageLayout.Content>
58
- + </PageLayout>
59
- --- Aside.tsx
60
- +++ Aside.tsx
61
- -import {AsideHeader} from '@gravity-ui/navigation';
62
- +import {PageLayoutAside} from '@gravity-ui/navigation';
63
-
64
- export const Aside: FC = () => {
65
- return (
66
- - <AsideHeader {...props}>
67
- + <PageLayoutAside {...props}/>
68
- );
69
- };
70
- ```
71
-
72
- ## Imports
73
-
74
- ```ts
75
- import {AsideHeader} from '@gravity-ui/navigation';
76
- ```
77
-
78
35
  ## CSS variables
79
36
 
80
37
  Used for themization Navigation's components
81
-
82
- ### AsideHeader vars
83
-
84
- | Name | Description | Default |
85
- | :-------------------------------------------------------- | :------------------------------------------------------------ | :----------------------------: |
86
- | `--gn-aside-header-decoration-collapsed-background-color` | Decoration color for collapsed navigation | `--g-color-base-warning-light` |
87
- | `--gn-aside-header-decoration-expanded-background-color` | Decoration color for expanded navigation | `--g-color-base-warning-light` |
88
- | `--gn-aside-header-background-color` | Navigation background color | `--g-color-base-background` |
89
- | `--gn-aside-header-divider-horizontal-color` | All horizontal divider line color | `--g-color-line-generic` |
90
- | `--gn-aside-header-divider-vertical-color` | Vertical divider line color between `AsideHeader` and content | `--g-color-line-generic` |
91
- | `--gn-aside-top-panel-height` | **Read only**.`AsideHeader` top alert height | 0px |
92
- | Item | | |
93
- | `--gn-aside-header-general-item-icon-color` | Icon color for Subheader and Footer items | `--g-color-text-primary` |
94
- | `--gn-aside-header-item-icon-color` | Icon color for CompositeBar items | `--g-color-text-misc` |
95
- | `--gn-aside-header-item-text-color` | | `--g-color-text-primary` |
96
- | `--gn-aside-header-item-background-color-hover` | | `--g-color-base-simple-hover` |
97
- | Current Item | | |
98
- | `--gn-aside-header-item-current-background-color` | | `--g-color-base-selection` |
99
- | `--gn-aside-header-item-current-icon-color` | | |
100
- | `--gn-aside-header-item-current-text-color` | | `--g-color-text-primary` |
101
- | `--gn-aside-header-item-current-background-color-hover` | | |
102
- | z-indexes | | |
103
- | `--gn-aside-header-z-index` | Aside header z-index | 100 |
104
- | `--gn-aside-header-panel-z-index` | Aside header panel (Drawer component) z-index | 98 |
105
- | `--gn-aside-header-pane-top-z-index` | Top pane z-index | 98 |
106
- | `--gn-aside-header-content-z-index` | Content (right part) z-index | 95 |
@@ -5,7 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var tslib_es6 = require('./tslib.es6-705c6589.js');
6
6
  var React = require('react');
7
7
  var PageLayout = require('./PageLayout.js');
8
- var PageLayoutAside = require('./PageLayoutAside-3fd5e2be.js');
8
+ var PageLayoutAside = require('./PageLayoutAside-b7365f95.js');
9
9
  require('./Content-64d5738a.js');
10
10
  require('./constants-d81c3867.js');
11
11
  require('./AsideHeaderContext.js');
@@ -11,7 +11,26 @@ require('@bem-react/classname');
11
11
 
12
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
13
 
14
+ function _interopNamespace(e) {
15
+ if (e && e.__esModule) return e;
16
+ var n = Object.create(null);
17
+ if (e) {
18
+ Object.keys(e).forEach(function (k) {
19
+ if (k !== 'default') {
20
+ var d = Object.getOwnPropertyDescriptor(e, k);
21
+ Object.defineProperty(n, k, d.get ? d : {
22
+ enumerable: true,
23
+ get: function () { return e[k]; }
24
+ });
25
+ }
26
+ });
27
+ }
28
+ n["default"] = e;
29
+ return Object.freeze(n);
30
+ }
31
+
14
32
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
33
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
15
34
  var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
16
35
 
17
36
  function _extends() {
@@ -3033,18 +3052,109 @@ SwitchTransition.defaultProps = {
3033
3052
  mode: modes.out
3034
3053
  };
3035
3054
 
3036
- var css_248z = ".gn-drawer__item{background-color:var(--g-color-base-background);bottom:0;height:100%;left:0;position:absolute;top:0;will-change:transform}.gn-drawer__item_direction_right{left:auto;right:0}.gn-drawer__item-transition-enter{transform:translate(-100%)}.gn-drawer__item-transition_direction_right-enter{transform:translate(100%)}.gn-drawer__item-transition-enter-active,.gn-drawer__item-transition_direction_right-enter-active{transform:translate(0);transition:transform .3s}.gn-drawer__item-transition-enter-done,.gn-drawer__item-transition_direction_right-enter-done{filter:blur(0);transform:translateZ(0)}.gn-drawer__item-transition-exit,.gn-drawer__item-transition_direction_right-exit{transform:translate(0)}.gn-drawer__item-transition-exit-active,.gn-drawer__item-transition_direction_right-exit-active{transition:transform .3s}.gn-drawer__item-transition-exit-active{transform:translate(-100%)}.gn-drawer__item-transition_direction_right-exit-active{transform:translate(100%)}.gn-drawer__item-transition-exit-done,.gn-drawer__item-transition_direction_right-exit-done{visibility:hidden}.gn-drawer__veil{background-color:var(--g-color-sfx-veil);inset:0;position:absolute}.gn-drawer__veil-transition-enter{opacity:0}.gn-drawer__veil-transition-enter-active{opacity:1;transition:opacity .3s}.gn-drawer__veil-transition-exit{opacity:1}.gn-drawer__veil-transition-exit-active{opacity:0;transition:opacity .3s}.gn-drawer__veil-transition-exit-done{visibility:hidden}";
3055
+ const DRAWER_ITEM_MIN_RESIZE_WIDTH = 200;
3056
+ const DRAWER_ITEM_MAX_RESIZE_WIDTH = 800;
3057
+ const DRAWER_ITEM_INITIAL_RESIZE_WIDTH = 400;
3058
+ function getEventClientX(e) {
3059
+ var _a, _b;
3060
+ return 'touches' in e ? (_b = (_a = e.touches[0]) === null || _a === void 0 ? void 0 : _a.clientX) !== null && _b !== void 0 ? _b : 0 : e.clientX;
3061
+ }
3062
+ function useResizeHandlers({ onStart, onMove, onEnd }) {
3063
+ const initialXPosition = React__namespace.useRef(0);
3064
+ const currentXPosition = React__namespace.useRef(0);
3065
+ const handleMove = React__namespace.useCallback((e) => {
3066
+ const currentX = getEventClientX(e);
3067
+ if (currentXPosition.current === currentX) {
3068
+ return;
3069
+ }
3070
+ currentXPosition.current = currentX;
3071
+ const delta = initialXPosition.current - currentX;
3072
+ onMove(delta);
3073
+ }, [onMove]);
3074
+ const handleEnd = React__namespace.useCallback((e) => {
3075
+ window.removeEventListener('mousemove', handleMove);
3076
+ window.removeEventListener('touchmove', handleMove);
3077
+ document.body.style.removeProperty('user-select');
3078
+ document.body.style.removeProperty('-webkit-user-select');
3079
+ document.body.style.removeProperty('cursor');
3080
+ const currentX = getEventClientX(e);
3081
+ const delta = initialXPosition.current - currentX;
3082
+ onEnd(delta);
3083
+ }, [handleMove, onEnd]);
3084
+ const handleStart = React__namespace.useCallback((e) => {
3085
+ const currentX = getEventClientX(e);
3086
+ initialXPosition.current = currentX;
3087
+ currentXPosition.current = currentX;
3088
+ window.addEventListener('mouseup', handleEnd, { once: true });
3089
+ window.addEventListener('touchend', handleEnd, { once: true });
3090
+ window.addEventListener('touchcancel', handleEnd, { once: true });
3091
+ window.addEventListener('mousemove', handleMove);
3092
+ window.addEventListener('touchmove', handleMove);
3093
+ document.body.style.setProperty('user-select', 'none');
3094
+ document.body.style.setProperty('-webkit-user-select', 'none');
3095
+ document.body.style.setProperty('cursor', 'col-resize');
3096
+ onStart();
3097
+ }, [handleEnd, handleMove, onStart]);
3098
+ return {
3099
+ onMouseDown: handleStart,
3100
+ onTouchStart: handleStart,
3101
+ };
3102
+ }
3103
+ function useResizableDrawerItem(params) {
3104
+ const { direction, width, minResizeWidth = DRAWER_ITEM_MIN_RESIZE_WIDTH, maxResizeWidth = DRAWER_ITEM_MAX_RESIZE_WIDTH, onResize, } = params;
3105
+ const [isResizing, setIsResizing] = React__namespace.useState(false);
3106
+ const [resizeDelta, setResizeDelta] = React__namespace.useState(0);
3107
+ const [internalWidth, setInternalWidth] = React__namespace.useState(width !== null && width !== void 0 ? width : DRAWER_ITEM_INITIAL_RESIZE_WIDTH);
3108
+ const getClampedWidth = React__namespace.useCallback((width) => Math.min(Math.max(width, minResizeWidth), maxResizeWidth), [minResizeWidth, maxResizeWidth]);
3109
+ const getResizedWidth = React__namespace.useCallback((delta) => {
3110
+ const signedDelta = direction === 'right' ? delta : -delta;
3111
+ const newWidth = (width !== null && width !== void 0 ? width : internalWidth) + signedDelta;
3112
+ return getClampedWidth(newWidth);
3113
+ }, [width, internalWidth, direction, getClampedWidth]);
3114
+ const onStart = React__namespace.useCallback(() => {
3115
+ setIsResizing(true);
3116
+ setResizeDelta(0);
3117
+ }, [setIsResizing, setResizeDelta]);
3118
+ const onMove = React__namespace.useCallback((delta) => {
3119
+ setResizeDelta(delta);
3120
+ }, []);
3121
+ const onEnd = React__namespace.useCallback((delta) => {
3122
+ const newWidth = getResizedWidth(delta);
3123
+ setIsResizing(false);
3124
+ setInternalWidth(newWidth);
3125
+ onResize === null || onResize === void 0 ? void 0 : onResize(newWidth);
3126
+ }, [setIsResizing, setInternalWidth, getResizedWidth, onResize]);
3127
+ const displayWidth = isResizing
3128
+ ? getResizedWidth(resizeDelta)
3129
+ : getClampedWidth(width !== null && width !== void 0 ? width : internalWidth);
3130
+ const handlers = useResizeHandlers({ onStart, onMove, onEnd });
3131
+ return { resizedWidth: displayWidth, resizerHandlers: handlers };
3132
+ }
3133
+
3134
+ var css_248z = ".gn-drawer{--_--resizer-width:8px;--_--resizer-color:var(--g-color-base-generic);--_--resizer-handle-color:var(--g-color-line-generic);--_--resizer-handle-color-hover:var(--g-color-line-generic-hover);--_--resizer-z-index:100;pointer-events:none}.gn-drawer__item{background-color:var(--g-color-base-background);bottom:0;height:100%;left:0;pointer-events:auto;position:absolute;top:0;will-change:transform}.gn-drawer__item_direction_right{left:auto;right:0}.gn-drawer__item-transition-enter{transform:translate(-100%)}.gn-drawer__item-transition_direction_right-enter{transform:translate(100%)}.gn-drawer__item-transition-enter-active,.gn-drawer__item-transition_direction_right-enter-active{transform:translate(0);transition:transform .3s}.gn-drawer__item-transition-enter-done,.gn-drawer__item-transition_direction_right-enter-done{filter:blur(0);transform:translateZ(0)}.gn-drawer__item-transition-exit,.gn-drawer__item-transition_direction_right-exit{transform:translate(0)}.gn-drawer__item-transition-exit-active,.gn-drawer__item-transition_direction_right-exit-active{transition:transform .3s}.gn-drawer__item-transition-exit-active{transform:translate(-100%)}.gn-drawer__item-transition_direction_right-exit-active{transform:translate(100%)}.gn-drawer__item-transition-exit-done,.gn-drawer__item-transition_direction_right-exit-done{visibility:hidden}.gn-drawer__veil{background-color:var(--g-color-sfx-veil);inset:0;pointer-events:auto;position:absolute}.gn-drawer__veil_hidden{display:none}.gn-drawer__veil-transition-enter{opacity:0}.gn-drawer__veil-transition-enter-active{opacity:1;transition:opacity .3s}.gn-drawer__veil-transition-exit{opacity:1}.gn-drawer__veil-transition-exit-active{opacity:0;transition:opacity .3s}.gn-drawer__veil-transition-exit-done{visibility:hidden}.gn-drawer__resizer-handle{background:var(--gn-drawer-item-resizer-handle-color,var(--_--resizer-handle-color));border-radius:2px;height:28px;width:2px}.gn-drawer__resizer{align-items:center;background:var(--gn-drawer-item-resizer-color,var(--_--resizer-color));cursor:col-resize;display:flex;flex-direction:column;height:100%;justify-content:center;position:absolute;top:0;width:var(--gn-drawer-item-resizer-width,var(--_--resizer-width));z-index:var(--gn-drawer-item-resizer-z-index,var(--_--resizer-z-index))}.gn-drawer__resizer_direction_right{left:0}.gn-drawer__resizer_direction_left{right:0}.gn-drawer__resizer:hover .gn-drawer__resizer-handle{background:var(--gn-drawer-item-resizer-handle-color-hover,var(--_--resizer-handle-color-hover))}";
3037
3135
  styleInject_es.styleInject(css_248z);
3038
3136
 
3039
3137
  const b = cn.block('drawer');
3040
3138
  const TIMEOUT = 300;
3041
- const DrawerItem = ({ visible, content, children, direction = 'left', className, }) => {
3139
+ const DrawerItem = React__default["default"].forwardRef(function DrawerItem(props, ref) {
3140
+ const { visible, content, children, direction = 'left', className, resizable, width, minResizeWidth, maxResizeWidth, onResize, } = props;
3042
3141
  const itemRef = React__default["default"].useRef(null);
3142
+ const handleRef = uikit.useForkRef(ref, itemRef);
3043
3143
  const cssDirection = direction === 'left' ? undefined : direction;
3144
+ const { resizedWidth, resizerHandlers } = useResizableDrawerItem({
3145
+ direction,
3146
+ width,
3147
+ minResizeWidth,
3148
+ maxResizeWidth,
3149
+ onResize,
3150
+ });
3151
+ const resizerElement = resizable ? (React__default["default"].createElement("div", Object.assign({ className: b('resizer', { direction }) }, resizerHandlers),
3152
+ React__default["default"].createElement("div", { className: b('resizer-handle') }))) : null;
3044
3153
  return (React__default["default"].createElement(CSSTransition, { in: visible, timeout: TIMEOUT, unmountOnExit: true, classNames: b('item-transition', { direction: cssDirection }), nodeRef: itemRef },
3045
- React__default["default"].createElement("div", { ref: itemRef, className: b('item', { direction: cssDirection }, className) }, children !== null && children !== void 0 ? children : content)));
3046
- };
3047
- const Drawer = ({ className, children, style, onVeilClick, onEscape, preventScrollBody = true, }) => {
3154
+ React__default["default"].createElement("div", { ref: handleRef, className: b('item', { direction: cssDirection }, className), style: { width: resizable ? `${resizedWidth}px` : undefined } },
3155
+ resizerElement, children !== null && children !== void 0 ? children : content)));
3156
+ });
3157
+ const Drawer = ({ className, children, style, onVeilClick, onEscape, preventScrollBody = true, hideVeil, disablePortal, }) => {
3048
3158
  let someItemVisible = false;
3049
3159
  React__default["default"].Children.forEach(children, (child) => {
3050
3160
  if (React__default["default"].isValidElement(child) && child.type === DrawerItem) {
@@ -3070,11 +3180,11 @@ const Drawer = ({ className, children, style, onVeilClick, onEscape, preventScro
3070
3180
  uikit.useBodyScrollLock({ enabled: preventScrollBody && someItemVisible });
3071
3181
  const containerRef = React__default["default"].useRef(null);
3072
3182
  const veilRef = React__default["default"].useRef(null);
3073
- return (React__default["default"].createElement(Transition, { in: someItemVisible, timeout: { enter: 0, exit: TIMEOUT }, mountOnEnter: true, unmountOnExit: true, nodeRef: containerRef }, (state) => {
3183
+ const drawer = (React__default["default"].createElement(Transition, { in: someItemVisible, timeout: { enter: 0, exit: TIMEOUT }, mountOnEnter: true, unmountOnExit: true, nodeRef: containerRef }, (state) => {
3074
3184
  const childrenVisible = someItemVisible && state === 'entered';
3075
3185
  return (React__default["default"].createElement("div", { ref: containerRef, className: b(null, className), style: style },
3076
3186
  React__default["default"].createElement(CSSTransition, { in: childrenVisible, timeout: TIMEOUT, unmountOnExit: true, classNames: b('veil-transition'), nodeRef: veilRef },
3077
- React__default["default"].createElement("div", { ref: veilRef, className: b('veil'), onClick: onVeilClick })),
3187
+ React__default["default"].createElement("div", { ref: veilRef, className: b('veil', { hidden: hideVeil }), onClick: onVeilClick })),
3078
3188
  React__default["default"].Children.map(children, (child) => {
3079
3189
  if (React__default["default"].isValidElement(child) &&
3080
3190
  child.type === DrawerItem) {
@@ -3084,6 +3194,10 @@ const Drawer = ({ className, children, style, onVeilClick, onEscape, preventScro
3084
3194
  return child;
3085
3195
  })));
3086
3196
  }));
3197
+ if (disablePortal) {
3198
+ return drawer;
3199
+ }
3200
+ return React__default["default"].createElement(uikit.Portal, null, drawer);
3087
3201
  };
3088
3202
 
3089
3203
  exports.Drawer = Drawer;