Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README-ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ interface DashKitDnDWrapperProps {
}
```

- `dragImageSrc` — изображение для предпросмотра при перетаскивании элемента. По умолчанию используется прозрачный PNG-файл размером 1 пиксель в формате `base64`.
- `dragImageSrc` — необязательное изображение для предпросмотра при перетаскивании. По умолчанию отображается сам перетаскиваемый элемент `ActionPanel`.
- `onDragStart` — обратный вызов, срабатывающий при начале перетаскивания элемента из `ActionPanel`.
- `onDragEnd` — обратный вызов, срабатывающий при завершении перетаскивания элемента или его отмене.

Expand Down Expand Up @@ -472,7 +472,9 @@ const onDrop = (dropProps: ItemDropProps) => {
| `--dashkit-action-panel-item-color` | Цвет фона. |
| `--dashkit-action-panel-item-text-color` | Цвет текста. |
| `--dashkit-action-panel-item-color-hover` | Цвет фона при наведении. |
| `--dashkit-action-panel-item-color-dragging` | Цвет фона при перетаскивании. |
| `--dashkit-action-panel-item-text-color-hover` | Цвет текста при наведении. |
| `--dashkit-action-panel-item-text-color-dragging` | Цвет текста при перетаскивании. |
| Переменные оверлея | |
| `--dashkit-overlay-border-color` | Цвет границы. |
| `--dashkit-overlay-color` | Цвет фона. |
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ interface DashKitDnDWrapperProps {
}
```

- **dragImageSrc**: Drag image preview, by default used transparent 1px png base64
- **dragImageSrc**: Optional custom drag image. By default, the dragged ActionPanel item is shown as the preview.
- **onDragStart**: Callback called when element is dragged from ActionPanel
- **onDragEnd**: Callback called when element dropped or drag canceled

Expand Down Expand Up @@ -550,7 +550,9 @@ const onDrop = (dropProps: ItemDropProps) => {
| `--dashkit-action-panel-item-color` | Backgroud color |
| `--dashkit-action-panel-item-text-color` | Text color |
| `--dashkit-action-panel-item-color-hover` | Hover backgroud color |
| `--dashkit-action-panel-item-color-dragging` | Drag background color |
| `--dashkit-action-panel-item-text-color-hover` | Hover text color |
| `--dashkit-action-panel-item-text-color-dragging` | Drag text color |
| Overlay variables | |
| `--dashkit-overlay-border-color` | Border color |
| `--dashkit-overlay-color` | Background color |
Expand Down
92 changes: 66 additions & 26 deletions src/components/ActionPanel/ActionPanel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,28 @@
$show_panel_transform: translateX(-50%) translateY(0);
$hide_panel_transform: translateX(-50%) translateY(calc(100% + 20px));

--_--dashkit-action-panel-color: var(--dashkit-action-panel-color, var(--g-color-base-float));
--_--dashkit-action-panel-border-color: var(
--dashkit-action-panel-border-color,
var(--g-color-base-brand)
--_--dashkit-action-panel-color: var(
--dashkit-action-panel-color,
var(--g-color-base-float-heavy)
);
--_--dashkit-action-panel-border-color: var(--dashkit-action-panel-border-color, transparent);
--_--dashkit-action-panel-border-radius: var(
--dashkit-action-panel-border-radius,
var(--g-border-radius-xl)
var(--g-border-radius-2xl, 16px)
);

background-color: var(--_--dashkit-action-panel-color);
backdrop-filter: blur(18px);
position: fixed;
bottom: 20px;
display: flex;
width: max-content;
max-width: calc(100vw - 40px);
overflow-x: auto;
border-radius: var(--_--dashkit-action-panel-border-radius);
border: 2px solid var(--_--dashkit-action-panel-border-color);
padding: 8px;
outline: 2px solid var(--_--dashkit-action-panel-border-color);
outline-offset: -2px;
padding: 6px;
gap: 0;
left: 50%;
transform: $show_panel_transform;
Expand Down Expand Up @@ -48,52 +53,87 @@
--_--dashkit-action-panel-item-color: var(--dashkit-action-panel-item-color, transparent);
--_--dashkit-action-panel-item-text-color: var(
--dashkit-action-panel-item-text-color,
var(--g-color-text-primary)
var(--g-color-text-light-primary)
);
--_--dashkit-action-panel-item-color-hover: var(
--dashkit-action-panel-item-color-hover,
var(--g-color-base-simple-hover)
var(--g-color-base-light-simple-hover)
);
--_--dashkit-action-panel-item-color-dragging: var(
--dashkit-action-panel-item-color-dragging,
var(--g-color-base-float-heavy)
);
--_--dashkit-action-panel-item-text-color-hover: var(
--dashkit-action-panel-item-text-color-hover,
var(--g-color-text-primary)
var(--g-color-text-light-primary)
);

height: 68px;
width: 98px;
min-height: 40px;
max-width: 200px;
flex: 0 0 auto;
display: flex;
flex-direction: column;
gap: 4px;
justify-content: center;
align-items: center;
transition:
300ms color ease-in-out,
300ms background-color ease-in-out;
border-radius: 6px;
padding: 0 12px;
border-radius: var(--g-border-radius-xl);
padding: 0 16px;
box-sizing: border-box;
white-space: nowrap;
overflow: hidden;
background-color: var(--_--dashkit-action-panel-item-color);
color: var(--_--dashkit-action-panel-item-text-color);
will-change: color, backgroung-color;
cursor: pointer;

&:hover {
cursor: pointer;
&:hover,
&:focus-visible {
background-color: var(--_--dashkit-action-panel-item-color-hover);
color: var(--_--dashkit-action-panel-item-text-color-hover);
}

&_draggable {
// Keep rounded corners when Chrome captures the item as a native drag image.
transform: translate(0, 0);
cursor: grab;

&:hover,
&:active {
transform: translateY(-2px);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.15);
}

&:active {
cursor: grabbing;
}
}

&_dragging,
&_dragging:hover {
transform: translate(0, 0);
background-color: var(--_--dashkit-action-panel-item-color-dragging);
color: var(
--dashkit-action-panel-item-text-color-dragging,
var(--g-color-text-light-primary)
);
}

&_dragging-source-disabled,
&_dragging-source-disabled:hover {
opacity: 0.5;
box-shadow: none;
}
}

&__icon {
margin-bottom: 4px;
display: flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
}

&__title {
font-size: 13px;
min-width: 0;
font-size: 12px;
font-weight: 400;
line-height: 16px;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Expand Down
34 changes: 34 additions & 0 deletions src/components/ActionPanel/ActionPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,38 @@ const b = cn('dashkit-action-panel');

export const ActionPanelItemContainer = ({item}: {item: ActionPanelItem}) => {
const dndProps = useDnDItemProps(item);
const draggingClassName = `${b('item')}_dragging`;
const disabledSourceClassName = `${b('item')}_dragging-source-disabled`;
const disableSourceTimer = React.useRef<ReturnType<typeof setTimeout> | null>(null);

React.useEffect(
() => () => {
if (disableSourceTimer.current !== null) {
clearTimeout(disableSourceTimer.current);
}
},
[],
);

const onDragStart = (event: React.DragEvent<HTMLDivElement>) => {
const source = event.currentTarget;
source.classList.add(draggingClassName);
dndProps?.onDragStart(event);
// The native drag image captures the solid item before the panel source is disabled.
disableSourceTimer.current = setTimeout(() => {
source.classList.add(disabledSourceClassName);
disableSourceTimer.current = null;
}, 0);
};

const onDragEnd = (event: React.DragEvent<HTMLDivElement>) => {
if (disableSourceTimer.current !== null) {
clearTimeout(disableSourceTimer.current);
disableSourceTimer.current = null;
}
event.currentTarget.classList.remove(draggingClassName, disabledSourceClassName);
dndProps?.onDragEnd(event);
};

return (
<div
Expand All @@ -21,6 +53,8 @@ export const ActionPanelItemContainer = ({item}: {item: ActionPanelItem}) => {
onClick={item.onClick}
data-qa={item.qa}
{...dndProps}
onDragStart={dndProps ? onDragStart : undefined}
onDragEnd={dndProps ? onDragEnd : undefined}
>
<div className={b('icon')}>{item.icon}</div>
<div className={b('title')} title={item.title}>
Expand Down
14 changes: 7 additions & 7 deletions src/components/DashKit/__stories__/CssApiShowcase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,35 @@ export const CssApiShowcase: React.FC = () => {
() => [
{
id: 'chart',
icon: <Icon data={ChartColumn} />,
icon: <Icon data={ChartColumn} size={20} />,
title: 'Chart',
className: 'test',
qa: 'chart',
},
{
id: 'selector',
icon: <Icon data={Sliders} />,
icon: <Icon data={Sliders} size={20} />,
title: 'Selector',
qa: 'selector',
},
{
id: 'text',
icon: <Icon data={TextAlignLeft} />,
icon: <Icon data={TextAlignLeft} size={20} />,
title: 'Text',
},
{
id: 'header',
icon: <Icon data={Heading} />,
icon: <Icon data={Heading} size={20} />,
title: 'Header',
},
{
id: 'links',
icon: <Icon data={PlugConnection} />,
icon: <Icon data={PlugConnection} size={20} />,
title: 'Links',
},
{
id: 'tabs',
icon: <Icon data={Layers3Diagonal} />,
icon: <Icon data={Layers3Diagonal} size={20} />,
title: 'Tabs',
},
],
Expand Down Expand Up @@ -77,7 +77,7 @@ export const CssApiShowcase: React.FC = () => {
--dashkit-placeholder-opacity: 1;
}`}
</style>
<Demo title="CSS API">
<Demo title="Customization">
<DemoRow title="Component view">
<ActionPanel items={items} />
<DashKit editMode={true} config={getConfig()} />
Expand Down
4 changes: 2 additions & 2 deletions src/components/DashKit/__stories__/DashKit.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ export const Default = DefaultTemplate.bind({});
const ShowcaseTemplate: Story = () => <DashKitShowcase />;
export const Showcase = ShowcaseTemplate.bind({});

const CssApiShowcaseTemplate: Story<DashKitProps> = () => <CssApiShowcase />;
export const CSS_API = CssApiShowcaseTemplate.bind({});
const CustomizationTemplate: Story<DashKitProps> = () => <CssApiShowcase />;
export const Customization = CustomizationTemplate.bind({});

const DndShowcaseTemplate: Story<DashKitProps> = () => <DashKitDnDShowcase />;
export const DragNDrop = DndShowcaseTemplate.bind({});
Expand Down
9 changes: 5 additions & 4 deletions src/components/DashKitDnDWrapper/DashKitDnDWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ type DashKitDnDWrapperProps = {
children: React.ReactElement;
};

const defaultImageSrc =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';

export const DashKitDnDWrapper: React.FC<DashKitDnDWrapperProps> = (props) => {
const [dragProps, setDragProps] = React.useState<ItemDragProps | null>(null);

const dragImagePreview = React.useMemo(() => {
if (!props.dragImageSrc) {
return null;
}

const img = new Image();
img.src = props.dragImageSrc || defaultImageSrc;
img.src = props.dragImageSrc;
return img;
}, [props.dragImageSrc]);

Expand Down
7 changes: 5 additions & 2 deletions src/components/GridItem/GridItem.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
}

.react-grid-item.dropping {
// RGL's slot-sized dropping node follows the cursor; keep only its separate grid placeholder visible.
opacity: 0;
// Disable evety mouse event for dropping element placeholder
user-select: none;
pointer-events: none;
Expand Down Expand Up @@ -92,10 +94,11 @@
}

.react-grid-item.react-grid-placeholder {
--_-dashkit-placeholder-color: var(--dashkit-placeholder-color, #fc0);
--_-dashkit-placeholder-opacity: var(--dashkit-placeholder-opacity, 0.2);
--_-dashkit-placeholder-color: var(--dashkit-placeholder-color, var(--g-color-base-brand));
--_-dashkit-placeholder-opacity: var(--dashkit-placeholder-opacity, 0.1);

background: var(--_-dashkit-placeholder-color);
border-radius: var(--dashkit-grid-item-border-radius, 3px);
opacity: var(--_-dashkit-placeholder-opacity);
transition-duration: 100ms;
z-index: 2;
Expand Down
2 changes: 1 addition & 1 deletion src/context/DashKitDnDContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {DraggedOverItem, ItemDragProps} from '../shared/types';

export type DashKitDnDCtxShape = {
dragProps: ItemDragProps | null;
dragImagePreview: HTMLImageElement;
dragImagePreview: HTMLImageElement | null;
onDragStart: (e: React.DragEvent<Element>, itemDragProps: ItemDragProps) => void;
onDragEnd: (e: React.DragEvent<Element>) => void;
onDropDragOver?: (
Expand Down
Loading
Loading