ydb-embedded-ui 3.2.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/components/EntitiesCount/EntitiesCount.tsx +34 -0
  3. package/dist/components/EntitiesCount/i18n/en.json +3 -0
  4. package/dist/components/{AsideNavigation/Settings → EntitiesCount}/i18n/index.ts +2 -2
  5. package/dist/components/EntitiesCount/i18n/ru.json +3 -0
  6. package/dist/components/EntitiesCount/index.ts +1 -0
  7. package/dist/components/Fullscreen/Fullscreen.scss +7 -5
  8. package/dist/components/TabletsOverall/TabletsOverall.tsx +4 -4
  9. package/dist/components/TabletsStatistic/TabletsStatistic.tsx +56 -0
  10. package/dist/components/TabletsStatistic/index.ts +1 -0
  11. package/dist/containers/App/App.scss +4 -12
  12. package/dist/containers/AsideNavigation/AsideNavigation.scss +0 -18
  13. package/dist/containers/AsideNavigation/AsideNavigation.tsx +95 -33
  14. package/dist/containers/Heatmap/Heatmap.scss +0 -7
  15. package/dist/containers/Heatmap/Heatmap.tsx +203 -0
  16. package/dist/containers/Heatmap/HeatmapCanvas/HeatmapCanvas.js +2 -1
  17. package/dist/containers/Heatmap/index.ts +1 -0
  18. package/dist/containers/Node/Node.tsx +1 -1
  19. package/dist/containers/Storage/Storage.js +12 -19
  20. package/dist/containers/Tablets/Tablets.scss +0 -5
  21. package/dist/containers/Tablets/Tablets.tsx +172 -0
  22. package/dist/containers/Tablets/i18n/en.json +6 -0
  23. package/dist/{components/AsideNavigation → containers/Tablets}/i18n/index.ts +1 -1
  24. package/dist/containers/Tablets/i18n/ru.json +6 -0
  25. package/dist/containers/Tablets/index.ts +1 -0
  26. package/dist/containers/TabletsFilters/TabletsFilters.js +4 -8
  27. package/dist/containers/TabletsFilters/TabletsFilters.scss +6 -2
  28. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +4 -8
  29. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +7 -7
  30. package/dist/containers/Tenants/Tenants.js +1 -1
  31. package/dist/containers/UserSettings/UserSettings.tsx +4 -3
  32. package/dist/routes.ts +1 -1
  33. package/dist/store/reducers/{heatmap.js → heatmap.ts} +33 -18
  34. package/dist/store/reducers/settings.js +12 -2
  35. package/dist/types/api/compute.ts +1 -1
  36. package/dist/types/api/schema.ts +16 -3
  37. package/dist/types/store/heatmap.ts +51 -0
  38. package/dist/utils/constants.ts +1 -37
  39. package/dist/utils/getNodesColumns.js +7 -2
  40. package/dist/utils/tablet.ts +53 -0
  41. package/package.json +2 -1
  42. package/dist/components/AsideNavigation/AsideHeader.scss +0 -147
  43. package/dist/components/AsideNavigation/AsideHeader.tsx +0 -389
  44. package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.scss +0 -82
  45. package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.tsx +0 -138
  46. package/dist/components/AsideNavigation/AsideHeaderFooterSlot/AsideHeaderFooterSlot.tsx +0 -33
  47. package/dist/components/AsideNavigation/AsideHeaderFooterSlot/SlotsContext.tsx +0 -49
  48. package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.scss +0 -16
  49. package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.tsx +0 -37
  50. package/dist/components/AsideNavigation/CompositeBar/CompositeBar.scss +0 -108
  51. package/dist/components/AsideNavigation/CompositeBar/CompositeBar.tsx +0 -282
  52. package/dist/components/AsideNavigation/Content/Content.tsx +0 -35
  53. package/dist/components/AsideNavigation/Drawer/Drawer.scss +0 -76
  54. package/dist/components/AsideNavigation/Drawer/Drawer.tsx +0 -134
  55. package/dist/components/AsideNavigation/Drawer/index.ts +0 -1
  56. package/dist/components/AsideNavigation/Logo/Logo.scss +0 -43
  57. package/dist/components/AsideNavigation/Logo/Logo.tsx +0 -82
  58. package/dist/components/AsideNavigation/Settings/README.md +0 -92
  59. package/dist/components/AsideNavigation/Settings/Settings.scss +0 -128
  60. package/dist/components/AsideNavigation/Settings/Settings.tsx +0 -270
  61. package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.scss +0 -78
  62. package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.tsx +0 -141
  63. package/dist/components/AsideNavigation/Settings/SettingsSearch/SettingsSearch.tsx +0 -57
  64. package/dist/components/AsideNavigation/Settings/collect-settings.ts +0 -156
  65. package/dist/components/AsideNavigation/Settings/filter-settings.ts +0 -38
  66. package/dist/components/AsideNavigation/Settings/helpers.ts +0 -39
  67. package/dist/components/AsideNavigation/Settings/i18n/en.json +0 -5
  68. package/dist/components/AsideNavigation/Settings/i18n/ru.json +0 -5
  69. package/dist/components/AsideNavigation/Settings/index.ts +0 -1
  70. package/dist/components/AsideNavigation/constants.ts +0 -28
  71. package/dist/components/AsideNavigation/helpers.ts +0 -34
  72. package/dist/components/AsideNavigation/i18n/en.json +0 -4
  73. package/dist/components/AsideNavigation/i18n/ru.json +0 -4
  74. package/dist/components/AsideNavigation/icons.ts +0 -32
  75. package/dist/components/AsideNavigation/types.ts +0 -23
  76. package/dist/components/TabletsStatistic/TabletsStatistic.js +0 -58
  77. package/dist/containers/Heatmap/Heatmap.js +0 -244
  78. package/dist/containers/Tablets/Tablets.js +0 -228
@@ -1,16 +0,0 @@
1
- .nv-aside-header-tooltip {
2
- &.yc-popup {
3
- border: none;
4
- box-shadow: none;
5
-
6
- animation-name: none;
7
- }
8
-
9
- &__text {
10
- padding: 6px 12px;
11
-
12
- color: var(--yc-color-text-light-primary);
13
- border-radius: 4px;
14
- background-color: var(--yc-color-base-float-heavy);
15
- }
16
- }
@@ -1,37 +0,0 @@
1
- import React from 'react';
2
- import block from 'bem-cn-lite';
3
- import {Popup, PopupPlacement} from '@gravity-ui/uikit';
4
- import './AsideHeaderTooltip.scss';
5
-
6
- const b = block('nv-aside-header-tooltip');
7
- const popupPlacement: PopupPlacement = ['right'];
8
-
9
- export interface AsideHeaderTooltipProps {
10
- anchor: HTMLElement | null;
11
- text: React.ReactNode;
12
- }
13
-
14
- export const AsideHeaderTooltip: React.FC<AsideHeaderTooltipProps> = ({anchor, text}) => {
15
- const anchorRef = React.useRef(anchor);
16
-
17
- React.useEffect(() => {
18
- anchorRef.current = anchor;
19
- }, [anchor]);
20
- if (!anchor) {
21
- return null;
22
- }
23
-
24
- return (
25
- <Popup
26
- className={b()}
27
- open={true}
28
- anchorRef={anchorRef}
29
- placement={popupPlacement}
30
- disableEscapeKeyDown={true}
31
- disableOutsideClick={true}
32
- disableLayer={true}
33
- >
34
- <div className={b('text')}>{text}</div>
35
- </Popup>
36
- );
37
- };
@@ -1,108 +0,0 @@
1
- .nv-composite-bar {
2
- $class: &;
3
-
4
- flex: 1 0 auto;
5
-
6
- width: 100%;
7
- min-height: 40px;
8
-
9
- &__root-menu-item {
10
- cursor: pointer;
11
- }
12
-
13
- &__root-menu-item.yc-list__item_selected:not(&__root-menu-item_compact) {
14
- background-color: var(--yc-color-base-selection);
15
- }
16
-
17
- & &__root-menu-item_compact#{&}__root-menu-item {
18
- background-color: transparent;
19
- }
20
-
21
- &__menu-item {
22
- display: flex;
23
- align-items: center;
24
-
25
- width: 100%;
26
- height: 100%;
27
- }
28
-
29
- &__menu-icon-place {
30
- display: flex;
31
- flex-shrink: 0;
32
- justify-content: center;
33
- align-items: center;
34
-
35
- width: var(--nv-aside-header-min-width);
36
- height: 100%;
37
- }
38
-
39
- #{$class} &__menu-icon {
40
- color: var(--yc-color-text-misc);
41
- }
42
-
43
- &__menu-title {
44
- overflow: hidden;
45
-
46
- width: 100%;
47
-
48
- white-space: nowrap;
49
- text-overflow: ellipsis;
50
- }
51
-
52
- &__root-collapse-item {
53
- cursor: pointer;
54
- }
55
-
56
- &__collapse-item {
57
- display: flex;
58
- align-items: center;
59
-
60
- width: 100%;
61
- height: 100%;
62
- padding: 0 16px;
63
- }
64
-
65
- &__collapse-items-popup-content {
66
- padding: 4px 0;
67
- }
68
-
69
- &__link {
70
- display: flex;
71
- align-items: center;
72
-
73
- width: 100%;
74
- height: 100%;
75
-
76
- &,
77
- &:hover,
78
- &:active,
79
- &:visited,
80
- &:focus {
81
- text-decoration: none;
82
-
83
- color: inherit;
84
- outline: none;
85
- }
86
- }
87
-
88
- &__btn-icon {
89
- display: flex;
90
- justify-content: center;
91
- align-items: center;
92
-
93
- width: 100%;
94
- height: 100%;
95
-
96
- @at-root .yc-list__item_active &:not(&_current) {
97
- background-color: var(--yc-color-base-simple-hover);
98
- }
99
-
100
- &::before {
101
- border-radius: 0;
102
- }
103
-
104
- &_current {
105
- background-color: var(--yc-color-base-selection);
106
- }
107
- }
108
- }
@@ -1,282 +0,0 @@
1
- import React from 'react';
2
- import block from 'bem-cn-lite';
3
- import AutoSizer from 'react-virtualized-auto-sizer';
4
- import {List, Icon, Popup, PopupPlacement} from '@gravity-ui/uikit';
5
-
6
- import {AsideHeaderMenuItem} from '../types';
7
- import i18n from '../i18n';
8
- import {AsideHeaderTooltip} from '../AsideHeaderTooltip/AsideHeaderTooltip';
9
-
10
- import dotsIcon from '../../../assets/icons/dots.svg';
11
-
12
- import './CompositeBar.scss';
13
-
14
- const b = block('nv-composite-bar');
15
- export const ITEM_HEIGHT = 40;
16
- const POPUP_ITEM_HEIGHT = 28;
17
- const COLLAPSE_ITEM_ID = 'nv-collapse-item-id';
18
- const popupPlacement: PopupPlacement = ['right-start', 'right-end', 'right'];
19
-
20
- const getSelectedItemIndex = (items: AsideHeaderMenuItem[]) => {
21
- const index = items.findIndex(({current}) => Boolean(current));
22
- return index === -1 ? undefined : index;
23
- };
24
-
25
- interface ItemProps {
26
- item: AsideHeaderMenuItem;
27
- isCompact: boolean;
28
- collapseItems: AsideHeaderMenuItem[] | null;
29
- onMouseEnter?: () => void;
30
- onMouseLeave?: () => void;
31
- onClick?: () => void;
32
- }
33
-
34
- const Item: React.FC<ItemProps> = ({item, isCompact, collapseItems, onClick}) => {
35
- const [tooltipAnchor, setTooltipAnchor] = React.useState<HTMLDivElement | null>(null);
36
- const [open, toggleOpen] = React.useState<boolean>(false);
37
- const popupAnchor = React.useRef<HTMLDivElement>(null);
38
-
39
- const tooltipText = item.tooltipText || item.title;
40
- const iconSize = item.iconSize || 24;
41
- const isCollapseItem = item.id === COLLAPSE_ITEM_ID;
42
-
43
- const node = (
44
- <div
45
- className={b('menu-item')}
46
- ref={popupAnchor}
47
- onClick={() => {
48
- if (typeof item.onItemClick === 'function') {
49
- item.onItemClick(item, false);
50
- }
51
- if (isCollapseItem) {
52
- toggleOpen(!open);
53
- setTooltipAnchor(null);
54
- }
55
- onClick?.();
56
- }}
57
- >
58
- <div className={b('menu-icon-place')}>
59
- {isCompact ? (
60
- <React.Fragment>
61
- <div
62
- onMouseEnter={(event) => !open && setTooltipAnchor(event.currentTarget)}
63
- onMouseLeave={() => setTooltipAnchor(null)}
64
- className={b('btn-icon', {current: Boolean(item.current)})}
65
- >
66
- {item.icon && (
67
- <Icon data={item.icon} size={iconSize} className={b('menu-icon')} />
68
- )}
69
- </div>
70
- <AsideHeaderTooltip anchor={tooltipAnchor} text={tooltipText} />
71
- </React.Fragment>
72
- ) : (
73
- item.icon && (
74
- <Icon data={item.icon} size={iconSize} className={b('menu-icon')} />
75
- )
76
- )}
77
- </div>
78
- <div className={b('menu-title')} title={item.title}>
79
- {item.title}
80
- </div>
81
- {isCollapseItem && Array.isArray(collapseItems) && Boolean(popupAnchor.current) && (
82
- <Popup
83
- placement={popupPlacement}
84
- open={open}
85
- anchorRef={popupAnchor}
86
- onClose={() => toggleOpen(false)}
87
- >
88
- <div className={b('collapse-items-popup-content')}>
89
- <List
90
- itemClassName={b('root-collapse-item')}
91
- items={collapseItems}
92
- selectedItemIndex={getSelectedItemIndex(collapseItems)}
93
- itemHeight={POPUP_ITEM_HEIGHT}
94
- itemsHeight={collapseItems.length * POPUP_ITEM_HEIGHT}
95
- virtualized={false}
96
- filterable={false}
97
- sortable={false}
98
- renderItem={(collapseItem) => {
99
- const collapseNode = (
100
- <div
101
- className={b('collapse-item')}
102
- onClick={() => {
103
- if (typeof collapseItem.onItemClick === 'function') {
104
- collapseItem.onItemClick(collapseItem, true);
105
- }
106
- }}
107
- >
108
- {collapseItem.title}
109
- </div>
110
- );
111
- if (typeof collapseItem.itemWrapper === 'function') {
112
- return collapseItem.itemWrapper(
113
- collapseNode,
114
- collapseItem,
115
- true,
116
- isCompact,
117
- );
118
- }
119
-
120
- return collapseItem.link ? (
121
- <a href={collapseItem.link} className={b('link')}>
122
- {collapseNode}
123
- </a>
124
- ) : (
125
- collapseNode
126
- );
127
- }}
128
- />
129
- </div>
130
- </Popup>
131
- )}
132
- </div>
133
- );
134
-
135
- if (typeof item.itemWrapper === 'function') {
136
- return item.itemWrapper(node, item, false, isCompact) as React.ReactElement;
137
- }
138
-
139
- return item.link ? (
140
- <a href={item.link} className={b('link')}>
141
- {node}
142
- </a>
143
- ) : (
144
- node
145
- );
146
- };
147
- Item.displayName = 'Item';
148
-
149
- interface CompositeBarProps {
150
- items: AsideHeaderMenuItem[];
151
- isCompact: boolean;
152
- onClickItem?: (item: AsideHeaderMenuItem) => void;
153
- }
154
-
155
- interface CompositeBarState {
156
- height: string | number;
157
- activeItemIndex?: number;
158
- }
159
-
160
- interface OnResizeArgs {
161
- width: number;
162
- height: number;
163
- }
164
-
165
- export class CompositeBar extends React.Component<CompositeBarProps> {
166
- render() {
167
- return (
168
- <React.Fragment>
169
- <div className={b()} style={{height: this.state.height}}>
170
- {this.props.items.length !== 0 && (
171
- <AutoSizer onResize={this.onResize}>
172
- {({width, height}) => {
173
- const style = {
174
- width,
175
- height,
176
- };
177
- return <div style={style}>{this.renderMenu(height)}</div>;
178
- }}
179
- </AutoSizer>
180
- )}
181
- </div>
182
- </React.Fragment>
183
- );
184
- }
185
-
186
- state: CompositeBarState = {
187
- height: 'auto',
188
- activeItemIndex: undefined,
189
- };
190
-
191
- private currentItemsCount = 0;
192
- private skipCheckResize = false;
193
-
194
- private onResize = ({height}: OnResizeArgs) => {
195
- if (this.skipCheckResize) {
196
- this.skipCheckResize = false;
197
- return;
198
- }
199
-
200
- const desiredHeight = this.currentItemsCount * ITEM_HEIGHT;
201
- if (height < desiredHeight) {
202
- if (this.state.height !== desiredHeight) {
203
- this.skipCheckResize = true;
204
- this.setState({height: desiredHeight});
205
- }
206
- } else if (this.state.height !== 'auto') {
207
- this.skipCheckResize = true;
208
- this.setState({height: 'auto'});
209
- }
210
- };
211
-
212
- private renderMenu(height: number) {
213
- const {items, isCompact, onClickItem} = this.props;
214
- const capacity = Math.max(1, Math.floor(height / ITEM_HEIGHT));
215
- let listItems: AsideHeaderMenuItem[] | null;
216
- let collapseItems: AsideHeaderMenuItem[] | null = null;
217
- if (capacity === 1) {
218
- listItems = items.filter((item) => item.pinned);
219
- collapseItems = [...items.filter((item) => !item.pinned)];
220
- if (collapseItems.length > 0) {
221
- listItems.push(this.getCollapseItem());
222
- }
223
- } else if (capacity < items.length) {
224
- const extraCount = items.filter(
225
- (item, idx) => item.pinned && idx >= capacity - 1,
226
- ).length;
227
- const pinnedFlag = items.reduceRight(
228
- (acc, curr, idx) => {
229
- const useExtraCount = !curr.pinned && idx < capacity - 1 && acc.extraCount > 0;
230
- acc.flags.unshift(curr.pinned || useExtraCount);
231
- return {
232
- flags: acc.flags,
233
- extraCount: acc.extraCount - Number(useExtraCount),
234
- };
235
- },
236
- {flags: [] as boolean[], extraCount},
237
- ).flags;
238
- listItems = items.filter(
239
- (item, idx) => item.pinned || (idx < capacity - 1 && !pinnedFlag[idx]),
240
- );
241
- collapseItems = items.filter(
242
- (item, idx) => !item.pinned && (idx >= capacity - 1 || pinnedFlag[idx]),
243
- );
244
- if (collapseItems.length > 0) {
245
- listItems.push(this.getCollapseItem());
246
- }
247
- } else {
248
- listItems = [...items];
249
- }
250
- this.currentItemsCount = listItems.length;
251
-
252
- return (
253
- <List
254
- items={listItems}
255
- selectedItemIndex={isCompact ? undefined : getSelectedItemIndex(listItems)}
256
- itemHeight={ITEM_HEIGHT}
257
- itemClassName={b('root-menu-item', {compact: isCompact})}
258
- itemsHeight={listItems.length * ITEM_HEIGHT}
259
- virtualized={false}
260
- filterable={false}
261
- sortable={false}
262
- renderItem={(item) => (
263
- <Item
264
- item={item}
265
- isCompact={isCompact}
266
- collapseItems={collapseItems}
267
- onClick={() => onClickItem?.(item)}
268
- />
269
- )}
270
- />
271
- );
272
- }
273
-
274
- private getCollapseItem(): AsideHeaderMenuItem {
275
- return {
276
- id: COLLAPSE_ITEM_ID,
277
- title: i18n('label_more'),
278
- icon: dotsIcon,
279
- iconSize: 16,
280
- };
281
- }
282
- }
@@ -1,35 +0,0 @@
1
- import React from 'react';
2
-
3
- export type RenderContentType = (data: {size: number}) => React.ReactNode;
4
-
5
- interface ContentProps {
6
- renderContent?: RenderContentType;
7
- className?: string;
8
- size: number;
9
- }
10
-
11
- interface RenderContentProps {
12
- renderContent: RenderContentType;
13
- size: number;
14
- }
15
-
16
- const RenderContent: React.FC<RenderContentProps> = React.memo(({renderContent, size}) => {
17
- return <React.Fragment>{renderContent({size})}</React.Fragment>;
18
- });
19
-
20
- RenderContent.displayName = 'RenderContent';
21
-
22
- export const Content: React.FC<ContentProps> = ({size, className, renderContent}) => {
23
- return (
24
- <div
25
- className={className}
26
- style={{
27
- ...({'--nv-aside-header-size': `${size}px`} as React.CSSProperties),
28
- }}
29
- >
30
- {typeof renderContent === 'function' && (
31
- <RenderContent size={size} renderContent={renderContent} />
32
- )}
33
- </div>
34
- );
35
- };
@@ -1,76 +0,0 @@
1
- .nv-drawer {
2
- &__item {
3
- position: absolute;
4
- top: 0;
5
- bottom: 0;
6
- left: 0;
7
-
8
- height: 100%;
9
-
10
- background-color: var(--yc-color-base-background);
11
- will-change: transform;
12
- }
13
-
14
- &__item-transition-enter {
15
- transform: translate(-100%, 0);
16
- }
17
-
18
- &__item-transition-enter-active {
19
- transition: transform 300ms;
20
- transform: translate(0, 0);
21
- }
22
-
23
- &__item-transition-enter-done {
24
- // it is hack to prevent text blur after animation in any browsers
25
- filter: blur(0px);
26
-
27
- transform: translateZ(0);
28
- }
29
-
30
- &__item-transition-exit {
31
- transform: translate(0, 0);
32
- }
33
-
34
- &__item-transition-exit-active {
35
- transition: transform 300ms;
36
- transform: translate(-100%, 0);
37
- }
38
-
39
- &__item-transition-exit-done {
40
- visibility: hidden;
41
- }
42
-
43
- &__veil {
44
- position: absolute;
45
- top: 0;
46
- right: 0;
47
- bottom: 0;
48
- left: 0;
49
-
50
- background-color: var(--yc-color-sfx-veil);
51
- }
52
-
53
- &__veil-transition-enter {
54
- opacity: 0;
55
- }
56
-
57
- &__veil-transition-enter-active {
58
- opacity: 1;
59
-
60
- transition: opacity 300ms;
61
- }
62
-
63
- &__veil-transition-exit {
64
- opacity: 1;
65
- }
66
-
67
- &__veil-transition-exit-active {
68
- opacity: 0;
69
-
70
- transition: opacity 300ms;
71
- }
72
-
73
- &__veil-transition-exit-done {
74
- visibility: hidden;
75
- }
76
- }
@@ -1,134 +0,0 @@
1
- import React from 'react';
2
- import block from 'bem-cn-lite';
3
- import {CSSTransition, Transition} from 'react-transition-group';
4
- import './Drawer.scss';
5
-
6
- const b = block('nv-drawer');
7
- const TIMEOUT = 300;
8
-
9
- export interface DrawerItemProps {
10
- visible: boolean;
11
- className?: string;
12
- }
13
-
14
- export const DrawerItem: React.FC<DrawerItemProps> = ({className, visible, children}) => {
15
- return (
16
- <CSSTransition
17
- in={visible}
18
- timeout={TIMEOUT}
19
- unmountOnExit={true}
20
- classNames={b('item-transition')}
21
- >
22
- <div className={b('item', className)}>{children}</div>
23
- </CSSTransition>
24
- );
25
- };
26
-
27
- type DrawerChild = React.ReactElement<DrawerItemProps>;
28
-
29
- export interface DrawerProps {
30
- children: DrawerChild | DrawerChild[];
31
- preventSrcollBody?: boolean;
32
- className?: string;
33
- style?: React.CSSProperties;
34
- onVeilClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
35
- onEscape?: () => void;
36
- }
37
-
38
- export const Drawer: React.FC<DrawerProps> = ({
39
- className,
40
- children,
41
- style,
42
- onVeilClick,
43
- onEscape,
44
- preventSrcollBody = true,
45
- }) => {
46
- let someItemVisible = false;
47
- React.Children.forEach(children, (child) => {
48
- const childElem = child as DrawerChild;
49
- if (childElem.type === DrawerItem) {
50
- const childVisible = Boolean(childElem.props.visible);
51
- if (childVisible) {
52
- someItemVisible = true;
53
- }
54
- }
55
- });
56
-
57
- React.useEffect(() => {
58
- function onKeyDown(event: KeyboardEvent) {
59
- if (event.key === 'Escape') {
60
- onEscape?.();
61
- }
62
- }
63
- if (someItemVisible) {
64
- window.addEventListener('keydown', onKeyDown);
65
- }
66
- return () => {
67
- window.removeEventListener('keydown', onKeyDown);
68
- };
69
- }, [onEscape, someItemVisible]);
70
-
71
- React.useEffect(() => {
72
- const prevPreventSrcollBody = preventSrcollBody;
73
- const cleanupPreventScrollBody = () => {
74
- document.body.style.paddingRight = '';
75
- document.body.style.paddingBottom = '';
76
- document.body.style.overflow = '';
77
- };
78
- const setPreventScrollBody = () => {
79
- const vw = window.innerWidth - document.documentElement.clientWidth;
80
- const hw = window.innerHeight - document.documentElement.clientHeight;
81
- document.body.style.paddingRight = vw + 'px';
82
- document.body.style.paddingBottom = hw + 'px';
83
- document.body.style.overflow = 'hidden';
84
- };
85
- if (prevPreventSrcollBody) {
86
- if (someItemVisible) {
87
- setPreventScrollBody();
88
- } else {
89
- cleanupPreventScrollBody();
90
- }
91
- }
92
- return () => {
93
- if (prevPreventSrcollBody) {
94
- cleanupPreventScrollBody();
95
- }
96
- };
97
- }, [someItemVisible, preventSrcollBody]);
98
-
99
- return (
100
- <Transition
101
- in={someItemVisible}
102
- timeout={{enter: 0, exit: TIMEOUT}}
103
- mountOnEnter
104
- unmountOnExit
105
- >
106
- {(state) => {
107
- const childrenVisible = someItemVisible && state === 'entered';
108
- return (
109
- <div className={b(null, className)} style={style}>
110
- <CSSTransition
111
- in={childrenVisible}
112
- timeout={TIMEOUT}
113
- unmountOnExit={true}
114
- classNames={b('veil-transition')}
115
- >
116
- <div className={b('veil')} onClick={onVeilClick} />
117
- </CSSTransition>
118
- {React.Children.map(children, (child) => {
119
- const childElem = child as DrawerChild;
120
- if (childElem.type === DrawerItem) {
121
- const childVisible = Boolean(childElem.props.visible);
122
- return React.cloneElement(childElem, {
123
- ...childElem.props,
124
- visible: childVisible && childrenVisible,
125
- });
126
- }
127
- return child;
128
- })}
129
- </div>
130
- );
131
- }}
132
- </Transition>
133
- );
134
- };
@@ -1 +0,0 @@
1
- export * from './Drawer';