ydb-embedded-ui 3.2.0 → 3.2.2

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 (78) hide show
  1. package/CHANGELOG.md +18 -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';