diff --git a/src/components/DashKit/__stories__/DashKitGroupsShowcase.tsx b/src/components/DashKit/__stories__/DashKitGroupsShowcase.tsx index 438e628..149bd68 100644 --- a/src/components/DashKit/__stories__/DashKitGroupsShowcase.tsx +++ b/src/components/DashKit/__stories__/DashKitGroupsShowcase.tsx @@ -1,7 +1,19 @@ import React from 'react'; -import {ChartColumn, Copy, Heading, Pin, Sliders, TextAlignLeft, TrashBin} from '@gravity-ui/icons'; -import {Button, Icon} from '@gravity-ui/uikit'; +import { + ArrowDown, + ArrowUp, + ChartColumn, + ChevronDown, + ChevronUp, + Copy, + Heading, + Pin, + Sliders, + TextAlignLeft, + TrashBin, +} from '@gravity-ui/icons'; +import {Button, Disclosure, Icon} from '@gravity-ui/uikit'; import { ActionPanel, @@ -29,9 +41,19 @@ const b = cn('stories-dashkit-showcase'); const MAX_ROWS = 2; const GRID_COLUMNS = 36; +function arrayMove(arr: string[], oldIndex: number, newIndex: number) { + const copy = [...arr]; + const item = copy[oldIndex]; + copy[oldIndex] = copy[newIndex]; + copy[newIndex] = item; + + return copy; +} + export const DashKitGroupsShowcase: React.FC = () => { const [editMode, setEditMode] = React.useState(true); const [headerInteractions, setHeaderInteractions] = React.useState(true); + const [chartGroups, setChartGroups] = React.useState(['1_group', '2_group']); const onClick = () => { console.log('click'); @@ -134,6 +156,91 @@ export const DashKitGroupsShowcase: React.FC = () => { }; }, }, + ...chartGroups.map((id) => ({ + id, + render: (id: string, children: React.ReactNode, props: DashkitGroupRenderProps) => { + const itemsLength = props.items.length; + const showPlaceholder = itemsLength === 0 && !props.isDragging; + + const isMultipleGroups = chartGroups.length > 1; + const groupIndex = chartGroups.indexOf(id); + const hasNext = isMultipleGroups && groupIndex < chartGroups.length - 1; + const hasPrev = isMultipleGroups && groupIndex > 0; + + return ( + +
+ {showPlaceholder ? ( +
+ Empty group +
+ ) : ( + children + )} +
+ + + {(props) => ( +
+
+ +
+
+ + +
+
+ )} +
+
+ ); + }, + })), { id: DEFAULT_GROUP, gridProperties: (props: ReactGridLayoutProps) => { @@ -146,7 +253,7 @@ export const DashKitGroupsShowcase: React.FC = () => { }, }, ], - [headerInteractions], + [headerInteractions, chartGroups], ); const overlayMenuItems = React.useMemo(() => { @@ -321,6 +428,18 @@ export const DashKitGroupsShowcase: React.FC = () => { ? 'Disable header interactions' : 'Enable header interactions'} + diff --git a/src/components/DashKit/__stories__/DashKitShowcase.scss b/src/components/DashKit/__stories__/DashKitShowcase.scss index 4de101f..d7b1141 100644 --- a/src/components/DashKit/__stories__/DashKitShowcase.scss +++ b/src/components/DashKit/__stories__/DashKitShowcase.scss @@ -31,4 +31,32 @@ flex: 1; } } + + &__collapse-group { + margin-bottom: 8px; + } + + &__collapse-group-placeholder { + flex: 1; + text-align: center; + } + + &__collapse-group-header { + display: flex; + } + + &__collapse-group-header-action { + flex-grow: 1; + } + + &__collapse-group-grid { + min-height: 52px; + display: flex; + flex-direction: column; + margin-top: 8px; + + > .react-grid-layout { + flex-grow: 1; + } + } } diff --git a/src/components/GridLayout/GridLayout.js b/src/components/GridLayout/GridLayout.js index 8aebbdb..2caacdf 100644 --- a/src/components/GridLayout/GridLayout.js +++ b/src/components/GridLayout/GridLayout.js @@ -748,6 +748,7 @@ export default class GridLayout extends React.PureComponent { items, layout, context, + isDragging: this.state.isDragging, }; return group.render(id, element, groupContext); } diff --git a/src/typings/config.ts b/src/typings/config.ts index 6a0719f..fe6ce8f 100644 --- a/src/typings/config.ts +++ b/src/typings/config.ts @@ -36,6 +36,7 @@ export type AddNewItemOptions = SetItemOptions & { export interface DashkitGroupRenderProps { config: Config; editMode: boolean; + isDragging: boolean; isMobile: boolean; items: ConfigItem[]; layout: ConfigLayout[];