@gravity-ui/navigation 3.3.9 → 3.4.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.
- package/build/cjs/components/Drawer/Drawer.d.ts +10 -2
- package/build/cjs/components/Drawer/__stories__/Drawer.stories.d.ts +1 -0
- package/build/cjs/components/Drawer/__stories__/ScrollLock.d.ts +3 -0
- package/build/cjs/components/Drawer/utils.d.ts +1 -0
- package/build/cjs/{index-wmJ_X61I.js → index-CLs1L-sq.js} +59 -25
- package/build/{esm/index-DFIDnNIV.js.map → cjs/index-CLs1L-sq.js.map} +1 -1
- package/build/cjs/{index-C751PFJy.js → index-ClUpN5oD.js} +2 -2
- package/build/cjs/{index-C751PFJy.js.map → index-ClUpN5oD.js.map} +1 -1
- package/build/cjs/index.js +1 -1
- package/build/esm/components/Drawer/Drawer.d.ts +10 -2
- package/build/esm/components/Drawer/__stories__/Drawer.stories.d.ts +1 -0
- package/build/esm/components/Drawer/__stories__/ScrollLock.d.ts +3 -0
- package/build/esm/components/Drawer/utils.d.ts +1 -0
- package/build/esm/{index-De4-cL6-.js → index-AHJjBN3a.js} +2 -2
- package/build/esm/{index-De4-cL6-.js.map → index-AHJjBN3a.js.map} +1 -1
- package/build/esm/{index-DFIDnNIV.js → index-CoM0LT-x.js} +59 -25
- package/build/{cjs/index-wmJ_X61I.js.map → esm/index-CoM0LT-x.js.map} +1 -1
- package/build/esm/index.js +1 -1
- package/package.json +1 -1
|
@@ -49,6 +49,8 @@ export interface DrawerItemProps {
|
|
|
49
49
|
* @default false
|
|
50
50
|
* */
|
|
51
51
|
keepMounted?: boolean;
|
|
52
|
+
/** Optional inline styles to be applied to the DrawerItem component. */
|
|
53
|
+
style?: React.CSSProperties;
|
|
52
54
|
}
|
|
53
55
|
export declare const DrawerItem: React.ForwardRefExoticComponent<DrawerItemProps & React.RefAttributes<HTMLDivElement>>;
|
|
54
56
|
type DrawerChild = React.ReactElement<DrawerItemProps>;
|
|
@@ -63,17 +65,23 @@ export interface DrawerProps {
|
|
|
63
65
|
veilClassName?: string;
|
|
64
66
|
/** Optional callback function that is called when the veil (overlay) is clicked. */
|
|
65
67
|
onVeilClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
|
66
|
-
/** Optional callback function that is called when the escape key is pressed
|
|
68
|
+
/** Optional callback function that is called when the escape key is pressed if the drawer is open. */
|
|
67
69
|
onEscape?: (event: KeyboardEvent) => void;
|
|
68
70
|
/** Optional flag to hide the background darkening */
|
|
69
71
|
hideVeil?: boolean;
|
|
70
|
-
/** Optional flag to
|
|
72
|
+
/** Optional flag to doesn't use `Portal` for drawer */
|
|
71
73
|
disablePortal?: boolean;
|
|
72
74
|
/**
|
|
73
75
|
* Keep child components mounted when closed
|
|
74
76
|
* @default false
|
|
75
77
|
* */
|
|
76
78
|
keepMounted?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Whether to lock page scroll when drawer is open.
|
|
81
|
+
* Applied only when hideVeil=true and disablePortal=false.
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
scrollLock?: boolean;
|
|
77
85
|
}
|
|
78
86
|
export declare const Drawer: React.FC<DrawerProps>;
|
|
79
87
|
export {};
|
|
@@ -5,4 +5,5 @@ export declare const Showcase: import("@storybook/csf").AnnotatedStoryFn<import(
|
|
|
5
5
|
export declare const ResizableItem: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, import("@storybook/csf").Args>;
|
|
6
6
|
export declare const DisablePortal: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, import("@storybook/csf").Args>;
|
|
7
7
|
export declare const HideVeil: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, import("@storybook/csf").Args>;
|
|
8
|
+
export declare const ScrollLock: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, import("@storybook/csf").Args>;
|
|
8
9
|
export declare const UsePortal: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, import("@storybook/csf").Args>;
|
|
@@ -5,6 +5,7 @@ export declare const DRAWER_ITEM_INITIAL_RESIZE_WIDTH = 400;
|
|
|
5
5
|
export type DrawerDirection = 'right' | 'left' | 'top' | 'bottom';
|
|
6
6
|
export type OnResizeHandler = (width: number, event: MouseEvent | TouchEvent) => void;
|
|
7
7
|
export type OnResizeContinueHandler = (width: number) => void;
|
|
8
|
+
export declare function useScrollLock(enabled: boolean): void;
|
|
8
9
|
export interface UseResizeHandlersParams {
|
|
9
10
|
onStart: () => void;
|
|
10
11
|
onMove: (delta: number) => void;
|
|
@@ -141,7 +141,7 @@ function styleInject(css, ref) {
|
|
|
141
141
|
var css_248z$u = ".g-root{--gn-aside-top-panel-height:0px}.gn-aside-header{--gn-aside-header-min-width:56px;--_--item-icon-background-size:38px;--_--background-color:var(--g-color-base-background);--_--decoration-collapsed-background-color:var(--g-color-base-warning-light);--_--decoration-expanded-background-color:var(--g-color-base-warning-light);--_--vertical-divider-line-color:var(--g-color-line-generic);--_--horizontal-divider-line-color:var(--g-color-line-generic);background-color:var(--g-color-base-background);height:100%;position:relative;width:100%}.gn-aside-header__aside{background-color:var(--gn-aside-header-expanded-background-color,var(--gn-aside-header-background-color,var(--_--background-color)));box-sizing:border-box;display:flex;flex-direction:column;height:100vh;left:0;margin-top:var(--gn-top-alert-height,0);max-height:calc(100vh - var(--gn-top-alert-height, 0));position:sticky;top:var(--gn-top-alert-height,0);width:inherit;z-index:var(--gn-aside-header-z-index,100)}.gn-aside-header__aside:after{background-color:var(--gn-aside-header-divider-vertical-color,var(--_--vertical-divider-line-color));content:\"\";height:100%;position:absolute;right:0;top:0;width:1px;z-index:2}.gn-aside-header__aside-popup-anchor{inset:0;position:absolute;z-index:1}.gn-aside-header__aside-content{--gradient-height:334px;display:flex;flex-direction:column;height:inherit;overflow-x:hidden;padding-top:var(--gn-aside-header-padding-top);position:relative;user-select:none;width:inherit;z-index:2}.gn-aside-header__aside-content>.gn-aside-header-logo{margin:8px 0}.gn-aside-header__aside-content_with-decoration{background:linear-gradient(180deg,var(--gn-aside-header-decoration-expanded-background-color,var(--_--decoration-expanded-background-color)) calc(var(--gradient-height)*.33),transparent calc(var(--gradient-height)*.88))}.gn-aside-header__aside-custom-background{bottom:0;display:flex;position:absolute;top:0;width:var(--gn-aside-header-size);z-index:-1}.gn-aside-header_compact .gn-aside-header__aside{background-color:var(--gn-aside-header-collapsed-background-color,var(--gn-aside-header-background-color,var(--_--background-color)))}.gn-aside-header_compact .gn-aside-header__aside-content{background:transparent}.gn-aside-header__header{--gn-aside-header-header-divider-height:29px;box-sizing:border-box;flex:none;padding-bottom:22px;padding-top:8px;position:relative;width:100%;z-index:1}.gn-aside-header__header .gn-aside-header__header-divider{bottom:0;color:var(--gn-aside-header-decoration-collapsed-background-color,var(--_--decoration-collapsed-background-color));display:none;left:0;position:absolute;z-index:-2}.gn-aside-header__header_with-decoration:before{background-color:var(--gn-aside-header-decoration-collapsed-background-color,var(--_--decoration-collapsed-background-color));content:\"\";display:none;height:calc(100% - var(--gn-aside-header-header-divider-height));left:0;position:absolute;top:0;width:100%;z-index:-2}.gn-aside-header__header:after{background-color:var(--gn-aside-header-divider-horizontal-color,var(--_--horizontal-divider-line-color));bottom:12px;content:\"\";height:1px;left:0;position:absolute;width:100%;z-index:-2}.gn-aside-header_compact .gn-aside-header__header:before,.gn-aside-header_compact .gn-aside-header__header_with-decoration .gn-aside-header__header-divider{display:block}.gn-aside-header_compact .gn-aside-header__header_with-decoration:after{display:none}.gn-aside-header__logo-button .gn-aside-header__logo-icon-place{height:var(--gn-aside-header-item-icon-background-size,var(--_--item-icon-background-size));width:var(--gn-aside-header-min-width)}.gn-aside-header__menu-items{flex-grow:1}.gn-aside-header__footer{display:flex;flex-direction:column;flex-shrink:0;margin:8px 0;width:100%}.gn-aside-header__panels{inset:var(--gn-top-alert-height,0) 0 0;max-height:calc(100vh - var(--gn-top-alert-height, 0));overflow:auto;position:fixed;z-index:var(--gn-aside-header-panel-z-index,98)}.gn-aside-header__panel{height:100%}.gn-aside-header__pane-container{display:flex;flex-direction:row;outline:none;overflow:visible;user-select:text}.gn-aside-header__top-alert{background:var(--g-color-base-background);position:fixed;top:0;width:100%;z-index:var(--gn-aside-header-pane-top-z-index,98)}.gn-aside-header__content{margin-top:var(--gn-top-alert-height,0);width:calc(100% - var(--gn-aside-header-size));z-index:var(--gn-aside-header-content-z-index,95)}";
|
|
142
142
|
styleInject(css_248z$u);
|
|
143
143
|
|
|
144
|
-
const TopAlert$1 = React.lazy(() => Promise.resolve().then(function () { return require('./index-
|
|
144
|
+
const TopAlert$1 = React.lazy(() => Promise.resolve().then(function () { return require('./index-ClUpN5oD.js'); }).then((module) => ({ default: module.TopAlert })));
|
|
145
145
|
const Layout = ({ compact, className, children, topAlert }) => {
|
|
146
146
|
const size = compact ? ASIDE_HEADER_COMPACT_WIDTH : ASIDE_HEADER_EXPANDED_WIDTH;
|
|
147
147
|
const asideHeaderContextValue = React.useMemo(() => ({ size, compact }), [compact, size]);
|
|
@@ -4393,6 +4393,17 @@ function getEventClientPosition(e, direction) {
|
|
|
4393
4393
|
}
|
|
4394
4394
|
return direction === 'horizontal' ? e.clientX : e.clientY;
|
|
4395
4395
|
}
|
|
4396
|
+
function useScrollLock(enabled) {
|
|
4397
|
+
React__namespace.useEffect(() => {
|
|
4398
|
+
if (!enabled)
|
|
4399
|
+
return;
|
|
4400
|
+
const originalStyle = window.getComputedStyle(document.body).overflow;
|
|
4401
|
+
document.body.style.overflow = 'hidden';
|
|
4402
|
+
return () => {
|
|
4403
|
+
document.body.style.overflow = originalStyle;
|
|
4404
|
+
};
|
|
4405
|
+
}, [enabled]);
|
|
4406
|
+
}
|
|
4396
4407
|
function useResizeHandlers({ onStart, onMove, onEnd, direction = 'horizontal', }) {
|
|
4397
4408
|
const initialPosition = React__namespace.useRef(0);
|
|
4398
4409
|
const currentPosition = React__namespace.useRef(0);
|
|
@@ -4430,7 +4441,7 @@ function useResizeHandlers({ onStart, onMove, onEnd, direction = 'horizontal', }
|
|
|
4430
4441
|
window.addEventListener('selectstart', disableSelect, { passive: false });
|
|
4431
4442
|
document.body.style.setProperty('cursor', direction === 'horizontal' ? 'col-resize' : 'row-resize');
|
|
4432
4443
|
onStart();
|
|
4433
|
-
}, [handleEnd, handleMove, onStart, direction]);
|
|
4444
|
+
}, [handleEnd, handleMove, onStart, direction, disableSelect]);
|
|
4434
4445
|
return {
|
|
4435
4446
|
onMouseDown: handleStart,
|
|
4436
4447
|
onTouchStart: handleStart,
|
|
@@ -4480,7 +4491,7 @@ styleInject(css_248z$l);
|
|
|
4480
4491
|
const b$m = block('drawer');
|
|
4481
4492
|
const TIMEOUT = 300;
|
|
4482
4493
|
const DrawerItem = React.forwardRef(function DrawerItem(props, ref) {
|
|
4483
|
-
const { visible, content, children, direction = 'left', className, resizable, width, minResizeWidth, maxResizeWidth, onResizeStart, onResizeContinue, onResize, keepMounted = false, } = props;
|
|
4494
|
+
const { visible, content, children, direction = 'left', className, resizable, width, minResizeWidth, maxResizeWidth, onResizeStart, onResizeContinue, onResize, keepMounted = false, style = {}, } = props;
|
|
4484
4495
|
const [isInitialRender, setInitialRender] = React.useState(true);
|
|
4485
4496
|
const itemRef = React.useRef(null);
|
|
4486
4497
|
const handleRef = uikit.useForkRef(ref, itemRef);
|
|
@@ -4494,15 +4505,18 @@ const DrawerItem = React.forwardRef(function DrawerItem(props, ref) {
|
|
|
4494
4505
|
onResize,
|
|
4495
4506
|
onResizeContinue,
|
|
4496
4507
|
});
|
|
4497
|
-
const
|
|
4498
|
-
|
|
4499
|
-
if (
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4508
|
+
const innerStyle = React.useMemo(() => {
|
|
4509
|
+
const css = Object.assign({}, style);
|
|
4510
|
+
if (resizable) {
|
|
4511
|
+
if (['left', 'right'].includes(direction)) {
|
|
4512
|
+
css.width = `${resizedWidth}px`;
|
|
4513
|
+
}
|
|
4514
|
+
else {
|
|
4515
|
+
css.height = `${resizedWidth}px`;
|
|
4516
|
+
}
|
|
4504
4517
|
}
|
|
4505
|
-
|
|
4518
|
+
return css;
|
|
4519
|
+
}, [direction, resizable, resizedWidth, style]);
|
|
4506
4520
|
React.useEffect(() => {
|
|
4507
4521
|
setInitialRender(true);
|
|
4508
4522
|
}, [direction]);
|
|
@@ -4513,10 +4527,10 @@ const DrawerItem = React.forwardRef(function DrawerItem(props, ref) {
|
|
|
4513
4527
|
direction: cssDirection,
|
|
4514
4528
|
hidden: isInitialRender && !visible,
|
|
4515
4529
|
resize: isResizing,
|
|
4516
|
-
}, [className]), style:
|
|
4530
|
+
}, [className]), style: innerStyle },
|
|
4517
4531
|
resizerElement, children !== null && children !== undefined ? children : content)));
|
|
4518
4532
|
});
|
|
4519
|
-
const Drawer = ({ className, veilClassName, children, style, onVeilClick, onEscape, hideVeil, disablePortal = true, keepMounted = false, }) => {
|
|
4533
|
+
const Drawer = ({ className, veilClassName, children, style, onVeilClick, onEscape, hideVeil, disablePortal = true, keepMounted = false, scrollLock = false, }) => {
|
|
4520
4534
|
let someItemVisible = false;
|
|
4521
4535
|
React.Children.forEach(children, (child) => {
|
|
4522
4536
|
if (React.isValidElement(child) && child.type === DrawerItem) {
|
|
@@ -4541,9 +4555,11 @@ const Drawer = ({ className, veilClassName, children, style, onVeilClick, onEsca
|
|
|
4541
4555
|
}, [onEscape, someItemVisible]);
|
|
4542
4556
|
const containerRef = React.useRef(null);
|
|
4543
4557
|
const veilRef = React.useRef(null);
|
|
4544
|
-
const
|
|
4558
|
+
const shouldApplyScrollLock = scrollLock && someItemVisible && hideVeil && !disablePortal;
|
|
4559
|
+
useScrollLock(shouldApplyScrollLock);
|
|
4560
|
+
return (React.createElement(Transition, { in: someItemVisible, timeout: { enter: 0, exit: TIMEOUT }, mountOnEnter: !keepMounted, unmountOnExit: !keepMounted, nodeRef: containerRef }, (state) => {
|
|
4545
4561
|
const childrenVisible = someItemVisible && state === 'entered';
|
|
4546
|
-
|
|
4562
|
+
const content = (React.createElement("div", { ref: containerRef, className: b$m({ hideVeil }, className), style: style },
|
|
4547
4563
|
React.createElement(CSSTransition, { in: childrenVisible, timeout: TIMEOUT, unmountOnExit: true, classNames: b$m('veil-transition'), nodeRef: veilRef },
|
|
4548
4564
|
React.createElement("div", { ref: veilRef, className: b$m('veil', { hidden: hideVeil }, veilClassName), onClick: onVeilClick })),
|
|
4549
4565
|
React.Children.map(children, (child) => {
|
|
@@ -4554,11 +4570,16 @@ const Drawer = ({ className, veilClassName, children, style, onVeilClick, onEsca
|
|
|
4554
4570
|
}
|
|
4555
4571
|
return child;
|
|
4556
4572
|
})));
|
|
4573
|
+
if (disablePortal) {
|
|
4574
|
+
return content;
|
|
4575
|
+
}
|
|
4576
|
+
// When hideVeil=true, we don't use FloatingOverlay to avoid blocking mouse events
|
|
4577
|
+
if (hideVeil) {
|
|
4578
|
+
return React.createElement(uikit.Portal, null, content);
|
|
4579
|
+
}
|
|
4580
|
+
return (React.createElement(uikit.Portal, null,
|
|
4581
|
+
React.createElement(FloatingOverlay, { lockScroll: true }, content)));
|
|
4557
4582
|
}));
|
|
4558
|
-
if (disablePortal) {
|
|
4559
|
-
return drawer;
|
|
4560
|
-
}
|
|
4561
|
-
return (React.createElement(uikit.Portal, null, someItemVisible ? React.createElement(FloatingOverlay, { lockScroll: true }, drawer) : drawer));
|
|
4562
4583
|
};
|
|
4563
4584
|
|
|
4564
4585
|
const Panels = () => {
|
|
@@ -5629,10 +5650,23 @@ styleInject(css_248z$5);
|
|
|
5629
5650
|
|
|
5630
5651
|
const b$5 = block('mobile-overlap-panel');
|
|
5631
5652
|
const OverlapPanel = ({ title, renderContent, className, onClose, action, closeTitle = i18n('overlap_button_close'), visible, topOffset, }) => {
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5653
|
+
const topOffsetValue = typeof topOffset === 'number' ? `${topOffset}px` : topOffset;
|
|
5654
|
+
const [itemPosition, setItemPosition] = React.useState();
|
|
5655
|
+
const drawerStyle = React.useMemo(() => ({ top: `calc(${topOffsetValue} + var(--gn-top-alert-height, 0px))` }), [topOffsetValue]);
|
|
5656
|
+
const drawerItemStyle = React.useMemo(() => itemPosition === 'absolute'
|
|
5657
|
+
? {}
|
|
5658
|
+
: { top: `calc(${topOffsetValue} + var(--gn-top-alert-height, 0px))` }, [topOffsetValue, itemPosition]);
|
|
5659
|
+
const itemRef = React.useRef(null);
|
|
5660
|
+
// It is necessary to determine the position of the DrawerItem in order to correctly set the top offset
|
|
5661
|
+
React.useLayoutEffect(() => {
|
|
5662
|
+
if (itemRef.current) {
|
|
5663
|
+
const style = getComputedStyle(itemRef.current);
|
|
5664
|
+
const position = style.position;
|
|
5665
|
+
setItemPosition(position);
|
|
5666
|
+
}
|
|
5667
|
+
}, []);
|
|
5668
|
+
return (React.createElement(Drawer, { className: b$5('', { action: Boolean(action) }, className), onVeilClick: onClose, onEscape: onClose, style: drawerStyle },
|
|
5669
|
+
React.createElement(DrawerItem, { id: "overlap", ref: itemRef, visible: visible, className: b$5('drawer-item'), style: drawerItemStyle },
|
|
5636
5670
|
React.createElement("div", { className: b$5('header') },
|
|
5637
5671
|
React.createElement(uikit.Button, { size: "l", view: "flat", className: b$5('close'), onClick: onClose, "aria-label": closeTitle },
|
|
5638
5672
|
React.createElement(uikit.Icon, { className: b$5('icon'), data: icons.ArrowLeft, size: MOBILE_HEADER_ICON_SIZE })),
|
|
@@ -5645,7 +5679,7 @@ const OverlapPanel = ({ title, renderContent, className, onClose, action, closeT
|
|
|
5645
5679
|
var css_248z$4 = ".gn-mobile-header{--mobile-header-min-heigth:50px;--mobile-header-icon-size:20px;background-color:var(--g-color-base-background)}.gn-mobile-header__header-container{background-color:var(--g-color-base-background);position:sticky;top:0;z-index:var(--gn-mobile-header-z-index,100)}.gn-mobile-header__header{align-items:center;border-bottom:1px solid var(--g-color-line-generic);box-sizing:border-box;display:flex;justify-content:space-between;padding:0 10px}.gn-mobile-header__burger{padding:12px}.gn-mobile-header__panel-item{--gn-drawer-item-position:var(--gn-mobile-header-panel-position,absolute)}.gn-mobile-header__burger-menu,.gn-mobile-header__panel-item{background-color:var(--g-color-base-background);max-height:100%;max-width:90vw;width:320px}.gn-mobile-header__user-menu{overflow-y:auto}.gn-mobile-header__overlap-panel,.gn-mobile-header__panels{z-index:var(--gn-mobile-header-panel-z-index,98)}.gn-mobile-header__panels{inset:var(--mobile-header-min-heigth) 0 0;overflow:hidden;position:fixed}.gn-mobile-header__panel-item{top:unset}.gn-mobile-header__content{overflow:auto}";
|
|
5646
5680
|
styleInject(css_248z$4);
|
|
5647
5681
|
|
|
5648
|
-
const TopAlert = React.lazy(() => Promise.resolve().then(function () { return require('./index-
|
|
5682
|
+
const TopAlert = React.lazy(() => Promise.resolve().then(function () { return require('./index-ClUpN5oD.js'); }).then((module) => ({ default: module.TopAlert })));
|
|
5649
5683
|
const b$4 = block('mobile-header');
|
|
5650
5684
|
const MobileHeader = React.forwardRef(({ logo, burgerMenu, burgerCloseTitle = i18n('burger_button_close'), burgerOpenTitle = i18n('burger_button_open'), panelItems = [], renderContent, sideItemRenderContent, onClosePanel, onEvent, className, contentClassName, overlapPanel, topAlert, }, ref) => {
|
|
5651
5685
|
const targetRef = useForwardRef(ref);
|
|
@@ -5961,4 +5995,4 @@ exports.styleInject = styleInject;
|
|
|
5961
5995
|
exports.useAsideHeaderContext = useAsideHeaderContext;
|
|
5962
5996
|
exports.useSettingsContext = useSettingsContext;
|
|
5963
5997
|
exports.useSettingsSelectionContext = useSettingsSelectionContext;
|
|
5964
|
-
//# sourceMappingURL=index-
|
|
5998
|
+
//# sourceMappingURL=index-CLs1L-sq.js.map
|