kibana/examples/grid_example/public/use_layout_styles.tsx
Hannah Mudge 1b25685667
[kbn-grid-layout] Flatten grid layout (#218900)
Closes https://github.com/elastic/kibana/issues/216096

## Summary

This PR accomplishes two main things:
1. It flattens out how grid elements are rendered, which means that
embeddables no longer re-mount when dragged between sections and
2. It allows panels and sections to be "intermixed" on a **single**
level (i.e. you can only drop a section header between panels if they
are **not** in a section)

Since this was a **major** rewrite of the grid layout logic, I also took
some time to clean up the code - this includes removing
`proposedGridLayout$` (since this added two sources of truth, which was
causing issues with the DOM becoming out-of-sync with the layout object;
however, this also caused
https://github.com/elastic/kibana/issues/220309) and unifying on the use
of "section" rather than "row" (since it was confusing that we were
using "row" for both the grid row number and the section ID).


https://github.com/user-attachments/assets/c5d9aa97-5b14-4f4c-aacf-74055c7d9c33

> [!NOTE]
> Reminder that, since collapsible sections aren't available in
Dashboard yet, you must test this PR in the `grid` example app (by
running Kibana with `yarn start --run-examples`).


### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: mbondyra <marta.bondyra@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Marta Bondyra <4283304+mbondyra@users.noreply.github.com>
2025-05-21 08:01:13 -06:00

102 lines
4.5 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { transparentize, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';
import { useMemo } from 'react';
/**
* This file was copy pasted from `src/platform/plugins/shared/dashboard/public/dashboard_renderer/grid/use_layout_styles.tsx`
* so that the styles in the example app could match those used in Dashboard
*/
export const useLayoutStyles = () => {
const { euiTheme } = useEuiTheme();
const layoutStyles = useMemo(() => {
const getRadialGradient = (position: string) => {
return `radial-gradient(
circle at ${position},
${euiTheme.colors.accentSecondary} 1px,
transparent 1px
)`;
};
/**
* TODO: We are currently using `euiTheme.colors.vis.euiColorVis0` for grid layout styles because it
* is the best choice available; however, once https://github.com/elastic/platform-ux-team/issues/586
* is resolved, we should swap these out for the drag-specific colour tokens
*/
return css`
--dashboardActivePanelBorderStyle: ${euiTheme.border.width.thick} solid
${euiTheme.colors.vis.euiColorVis0};
--dashboardHoverActionsActivePanelBoxShadow--singleWrapper: 0 0 0
${euiTheme.border.width.thin} ${euiTheme.colors.vis.euiColorVis0};
--dashboardHoverActionsActivePanelBoxShadow: -${euiTheme.border.width.thin} 0 ${euiTheme.colors.vis.euiColorVis0},
${euiTheme.border.width.thin} 0 ${euiTheme.colors.vis.euiColorVis0},
0 -${euiTheme.border.width.thin} ${euiTheme.colors.vis.euiColorVis0};
.kbnGridSection--targeted {
background-position: top calc((var(--kbnGridGutterSize) / 2) * -1px) left
calc((var(--kbnGridGutterSize) / 2) * -1px);
background-size: calc((var(--kbnGridColumnWidth) + var(--kbnGridGutterSize)) * 1px)
calc((var(--kbnGridRowHeight) + var(--kbnGridGutterSize)) * 1px);
background-image: ${getRadialGradient('top left')}, ${getRadialGradient('top right')},
${getRadialGradient('bottom left')}, ${getRadialGradient('bottom right')};
background-origin: content-box;
}
.kbnGridPanel--dragPreview {
background-color: ${transparentize(euiTheme.colors.vis.euiColorVis0, 0.2)};
}
.kbnGridPanel--resizeHandle {
z-index: ${euiTheme.levels.maskBelowHeader};
// applying mask via ::after allows for focus borders to show
&:after {
display: block;
width: 100%;
height: 100%;
content: '';
mask-repeat: no-repeat;
mask-position: bottom ${euiTheme.size.s} right ${euiTheme.size.s};
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8' fill='none'%3E%3Cg clip-path='url(%23clip0_472_172810)'%3E%3Ccircle cx='7' cy='1' r='1' fill='%23000000'/%3E%3C/g%3E%3Cg clip-path='url(%23clip1_472_172810)'%3E%3Ccircle cx='4' cy='4' r='1' fill='%23000000'/%3E%3Ccircle cx='7' cy='4' r='1' fill='%23000000'/%3E%3C/g%3E%3Cg clip-path='url(%23clip2_472_172810)'%3E%3Ccircle cx='1' cy='7' r='1' fill='%23000000'/%3E%3Ccircle cx='4' cy='7' r='1' fill='%23000000'/%3E%3Ccircle cx='7' cy='7' r='1' fill='%23000000'/%3E%3C/g%3E%3C/svg%3E");
background-color: ${euiTheme.colors.borderBaseFormsControl};
}
&:hover,
&:focus-visible {
&:after {
background-color: ${euiTheme.colors.vis.euiColorVis0};
}
}
}
.kbnGridPanel--active {
// overwrite the border style on panels + hover actions for active panels
--hoverActionsBorderStyle: var(--dashboardActivePanelBorderStyle);
--hoverActionsBoxShadowStyle: var(--dashboardHoverActionsActivePanelBoxShadow);
--hoverActionsSingleWrapperBoxShadowStyle: var(
--dashboardHoverActionsActivePanelBoxShadow--singleWrapper
);
// prevent the hover actions transition when active to prevent "blip" on resize
.embPanel__hoverActions {
transition: none;
}
}
`;
}, [euiTheme]);
return layoutStyles;
};