Skip to content

Commit

Permalink
12787 resizable testing feedback changes (#13154)
Browse files Browse the repository at this point in the history
* Add minimumsize to center columns on ux editor

* Remove onhover effect for resizing handles

* Use localStorage for collapsed state and preview default as opened

* Add overflow auto for x axis on properties panel

* Refactor function to reuse code

* Add throttling to resizing to avoid multiple resizes per render cycle

* Fix tests using userQuery in ux-editor

* Alter test to include case for resizing last element in container

* Remove unused code
  • Loading branch information
Jondyr authored Jul 16, 2024
1 parent ec91668 commit ede94f7
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
position: absolute;
}

.resizeHandle:hover:after {
background-color: rgba(0, 0, 0, 0.1);
}

.resizeHandleH {
cursor: col-resize;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const StudioResizableLayoutHandle = ({
const { resizeDelta, containerSize } = useStudioResizableLayoutContext(index);
const { onMouseDown, isResizing } = useStudioResizableLayoutMouseMovement(
orientation,
(delta, _) => {
(delta) => {
resizeDelta(index, delta);
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ describe('useStudioResizableLayoutFunctions', () => {

beforeEach(() => {
setContainerSize = jest.fn();
elementRefs = { current: [document.createElement('div'), document.createElement('div')] };
elementRefs = {
current: [document.createElement('div'), document.createElement('div')],
};
children = [
{ props: { collapsed: false, minimumSize: 0, maximumSize: 100, collapsedSize: 0 } },
{ props: { collapsed: false, minimumSize: 0, maximumSize: 100, collapsedSize: 0 } },
Expand All @@ -33,7 +35,7 @@ describe('useStudioResizableLayoutFunctions', () => {
it('should call resizeTo with correct parameters when resizeDelta is called', () => {
const { result } = renderFunctionsHook(elementRefs, children, setContainerSize);

result.current.resizeDelta(0, 100);
result.current.resizeDelta(1, 100);
expect(setContainerSize).toHaveBeenCalled();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ export const useStudioResizableLayoutFunctions = (
children: any[],
setContainerSize: (index: number, size: number) => void,
): useResizableFunctionsReturnType => {
const getElementNeighbour = (index: number): StudioResizableLayoutArea => {
const neighbourIndex = elementRefs.current.length < index + 2 ? index - 1 : index + 1;
return new StudioResizableLayoutArea(
neighbourIndex,
elementRefs.current[neighbourIndex],
children[neighbourIndex],
orientation,
);
};

const getElement = (index: number): StudioResizableLayoutArea => {
return new StudioResizableLayoutArea(
index,
Expand All @@ -32,6 +22,11 @@ export const useStudioResizableLayoutFunctions = (
);
};

const getElementNeighbour = (index: number): StudioResizableLayoutArea => {
const neighbourIndex = elementRefs.current.length < index + 2 ? index - 1 : index + 1;
return getElement(neighbourIndex);
};

const calculatePixelSizes = (
element: StudioResizableLayoutArea,
neighbour: StudioResizableLayoutArea,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
import { useRef, useCallback, useState } from 'react';
import { useRef, useCallback, useState, useEffect } from 'react';
import type { StudioResizableOrientation } from '../StudioResizableLayoutContainer/StudioResizableLayoutContainer';

export const useStudioResizableLayoutMouseMovement = (
orientation: StudioResizableOrientation,
onMousePosChange: (delta: number, position: number) => void,
onMousePosChange: (delta: number) => void,
): {
onMouseDown: (event: React.MouseEvent<HTMLDivElement>) => () => void;
isResizing: boolean;
} => {
const lastMousePosition = useRef<number>(0);
const startMousePosition = useRef<number>(0);
const [isResizing, setIsResizing] = useState(false);

// throttle mouseMove events to avoid calculating new size before last rerender
const update = useRef<number>(1);
const lastEventUpdate = useRef<number>(0);
useEffect(() => {
update.current++;
});

const mouseMove = useCallback(
(event: MouseEvent): void => {
if (update.current === lastEventUpdate.current) return;
lastEventUpdate.current = update.current;
const mousePos = orientation === 'horizontal' ? event.clientX : event.clientY;
const mouseTotalDelta = mousePos - startMousePosition.current;
const mouseDelta = mousePos - lastMousePosition.current;
onMousePosChange(mouseDelta, mouseTotalDelta);
onMousePosChange(mouseDelta);
lastMousePosition.current = mousePos;
},
[orientation, onMousePosChange],
);

const mouseUp = useCallback(
(_: MouseEvent): void => {
update.current = 1;
lastEventUpdate.current = 0;
setIsResizing(false);
window.removeEventListener('mousemove', mouseMove);
window.removeEventListener('mouseup', mouseUp);
Expand All @@ -38,7 +47,6 @@ export const useStudioResizableLayoutMouseMovement = (
event.preventDefault();
setIsResizing(true);
lastMousePosition.current = orientation === 'horizontal' ? event.clientX : event.clientY;
startMousePosition.current = lastMousePosition.current;
window.addEventListener('mousemove', mouseMove);
window.addEventListener('mouseup', mouseUp);
},
Expand Down
3 changes: 3 additions & 0 deletions frontend/packages/ux-editor/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import type { AppContextProps } from './AppContext';
import ruleHandlerMock from './testing/ruleHandlerMock';
import { layoutSetsMock } from './testing/layoutSetsMock';
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock';
import { user as userMock } from 'app-shared/mocks/mocks';
import { QueryKey } from 'app-shared/types/QueryKey';

const mockQueries: Partial<ServicesContextProps> = {
getInstanceIdForPreview: jest.fn().mockImplementation(() => Promise.resolve('test')),
Expand All @@ -24,6 +26,7 @@ const renderApp = (
appContextProps: Partial<AppContextProps> = {},
) => {
const queryClient = createQueryClientMock();
queryClient.setQueryData([QueryKey.CurrentUser], [userMock]);
return renderWithProviders(<App />, {
queries,
appContextProps,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.root {
background: var(--fds-semantic-surface-neutral-subtle);
flex: var(--properties-width-fraction);
overflow-x: auto;
}

.dataModelBindings {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { formItemContextProviderMock } from '../testing/formItemContextMocks';
import { appContextMock } from '../testing/appContextMock';
import { app, org } from '@studio/testing/testids';
import userEvent from '@testing-library/user-event';
import { user as userMock } from 'app-shared/mocks/mocks';

// Test data:
const defaultTexts: ITextResources = {
Expand All @@ -43,6 +44,7 @@ const render = () => {
[],
);
queryClient.setQueryData([QueryKey.TextResources, org, app], defaultTexts);
queryClient.setQueryData([QueryKey.CurrentUser], [userMock]);
return renderWithProviders(
<FormItemContext.Provider
value={{
Expand Down Expand Up @@ -154,10 +156,10 @@ describe('FormDesigner', () => {
expect(screen.queryByText(textMock('ux_editor.loading_form_layout'))).not.toBeInTheDocument(),
);

await user.click(screen.getByTitle(textMock('ux_editor.open_preview')));
expect(screen.getByTitle(textMock('ux_editor.close_preview'))).toBeInTheDocument();

await user.click(screen.getByTitle(textMock('ux_editor.close_preview')));
expect(screen.getByTitle(textMock('ux_editor.open_preview'))).toBeInTheDocument();

await user.click(screen.getByTitle(textMock('ux_editor.open_preview')));
expect(screen.getByTitle(textMock('ux_editor.close_preview'))).toBeInTheDocument();
});
});
23 changes: 16 additions & 7 deletions frontend/packages/ux-editor/src/containers/FormDesigner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useFormLayoutsQuery } from '../hooks/queries/useFormLayoutsQuery';
import { useFormLayoutSettingsQuery } from '../hooks/queries/useFormLayoutSettingsQuery';
import { useRuleModelQuery } from '../hooks/queries/useRuleModelQuery';
import { ErrorPage } from '../components/ErrorPage';
import { StudioPageSpinner, StudioResizableLayout } from '@studio/components';
import { StudioPageSpinner, StudioResizableLayout, useLocalStorage } from '@studio/components';
import { BASE_CONTAINER_ID } from 'app-shared/constants';
import { useRuleConfigQuery } from '../hooks/queries/useRuleConfigQuery';
import { useInstanceIdQuery, useUserQuery } from 'app-shared/hooks/queries';
Expand Down Expand Up @@ -63,8 +63,14 @@ export const FormDesigner = (): JSX.Element => {
selectedFormLayoutSetName,
);
const { handleEdit } = useFormItemContext();
const [previewCollapsed, setPreviewCollapsed] = useState<boolean>(true);
const [elementsCollapsed, setElementsCollapsed] = useState<boolean>(false);
const [previewCollapsed, setPreviewCollapsed] = useLocalStorage<boolean>(
`form-designer-main:previewCollapsed:${user.id}:${org}`,
false,
);
const [elementsCollapsed, setElementsCollapsed] = useLocalStorage<boolean>(
`form-designer-main:elementsCollapsed:${user.id}:${org}`,
false,
);
const [hidePreview, setHidePreview] = useState<boolean>(false);

const t = useText();
Expand Down Expand Up @@ -161,13 +167,16 @@ export const FormDesigner = (): JSX.Element => {
>
<Elements
collapsed={elementsCollapsed}
onCollapseToggle={() => setElementsCollapsed((prev) => !prev)}
onCollapseToggle={() => setElementsCollapsed(!elementsCollapsed)}
/>
</StudioResizableLayout.Element>
<StudioResizableLayout.Element>
<StudioResizableLayout.Element minimumSize={250}>
<DesignView />
</StudioResizableLayout.Element>
<StudioResizableLayout.Element onResizing={(resizing) => setHidePreview(resizing)}>
<StudioResizableLayout.Element
minimumSize={250}
onResizing={(resizing) => setHidePreview(resizing)}
>
<Properties />
</StudioResizableLayout.Element>
<StudioResizableLayout.Element
Expand All @@ -177,7 +186,7 @@ export const FormDesigner = (): JSX.Element => {
>
<Preview
collapsed={previewCollapsed}
onCollapseToggle={() => setPreviewCollapsed((prev) => !prev)}
onCollapseToggle={() => setPreviewCollapsed(!previewCollapsed)}
hidePreview={hidePreview}
/>
</StudioResizableLayout.Element>
Expand Down

0 comments on commit ede94f7

Please sign in to comment.