Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Task][WRS-2189] Change page on arrow key press, scrollbars behaviour #249

Merged
merged 11 commits into from
Jan 10, 2025
Merged
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"validate-versions": "node validate_versions.cjs"
},
"dependencies": {
"@chili-publish/grafx-shared-components": "^0.88.7",
"@chili-publish/grafx-shared-components": "https://stgrafxstudiodevpublic.blob.core.windows.net/grafx-shared-components/dev-shared-components/466/grafx-shared-components.tgz",
"@chili-publish/studio-sdk": "^1.17.2-rc.2",
"@babel/preset-env": "^7.25.3",
"@fortawesome/fontawesome-svg-core": "^6.7.1",
Expand Down
11 changes: 5 additions & 6 deletions src/components/layout-panels/leftPanel/LeftPanel.styles.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import { ITheme } from '@chili-publish/grafx-shared-components';
import styled from 'styled-components';
import { SCROLL_SIZE } from '../../../utils/constants';

export const LeftPanelContainer = styled.div<{ overflowScroll: boolean; panelTheme: ITheme['panel'] }>`
min-width: 18.75rem;
width: 18.75rem;
background-color: ${(props) => props.panelTheme.backgroundColor};
border-right: 2px solid ${(props) => props.panelTheme.borderColor};
${(props) => props.overflowScroll && 'overflow: scroll'};
padding-left: 0;

&::-webkit-scrollbar {
width: 0;
}
scollbar-gutter: stable;
`;

export const VariablesListContainer = styled.div<{ hidden: boolean }>`
padding: 0 1.25rem;
padding: 0 0 0 1.25rem;
width: calc(18.75rem - 1.5625rem - ${SCROLL_SIZE});
${({ hidden }) => hidden && 'display: none;'};
`;

export const ImagePanelContainer = styled.div<{ hidden: boolean }>`
padding: 0 0 0 1.25rem;
height: 100%;
width: calc(18.75rem - 1.25rem - ${SCROLL_SIZE});
${({ hidden }) => hidden && 'display: none;'};
`;
18 changes: 10 additions & 8 deletions src/components/layout-panels/leftPanel/LeftPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Variable } from '@chili-publish/studio-sdk';
import { useTheme } from '@chili-publish/grafx-shared-components';
import { ScrollbarWrapper, useTheme } from '@chili-publish/grafx-shared-components';
import { ImagePanelContainer, LeftPanelContainer, VariablesListContainer } from './LeftPanel.styles';
import ImagePanel from '../../imagePanel/ImagePanel';
import VariablesList from '../../variables/VariablesList';
Expand All @@ -25,14 +25,16 @@ function LeftPanel({ variables, isDocumentLoaded }: LeftPanelProps) {
overflowScroll={contentType !== ContentType.IMAGE_PANEL}
panelTheme={panel}
>
<VariablesListContainer hidden={contentType === ContentType.IMAGE_PANEL}>
{featureFlags?.STUDIO_DATA_SOURCE ? <DataSource isDocumentLoaded={isDocumentLoaded} /> : null}
<VariablesList variables={variables} isDocumentLoaded={isDocumentLoaded} />
</VariablesListContainer>
<ScrollbarWrapper>
<VariablesListContainer hidden={contentType === ContentType.IMAGE_PANEL}>
{featureFlags?.STUDIO_DATA_SOURCE ? <DataSource isDocumentLoaded={isDocumentLoaded} /> : null}
<VariablesList variables={variables} isDocumentLoaded={isDocumentLoaded} />
</VariablesListContainer>

<ImagePanelContainer hidden={contentType !== ContentType.IMAGE_PANEL}>
<ImagePanel />
</ImagePanelContainer>
<ImagePanelContainer hidden={contentType !== ContentType.IMAGE_PANEL}>
<ImagePanel />
</ImagePanelContainer>
</ScrollbarWrapper>
</LeftPanelContainer>
);
}
Expand Down
16 changes: 9 additions & 7 deletions src/components/pagesPanel/Pages.styles.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import { ITheme } from '@chili-publish/grafx-shared-components';
import styled from 'styled-components';
import { BORDER_SIZE, PAGES_CONTAINER_HEIGHT, SCROLL_SIZE } from '../../utils/constants';

export const Container = styled.div<{ themeStyles: ITheme; isMobileSize: boolean }>`
box-sizing: border-box;
display: flex;
justify-content: center;
max-width: ${({ isMobileSize }) => (!isMobileSize ? 'calc(100vw - 18.875rem)' : '100%')};
height: 7.5rem;
height: ${PAGES_CONTAINER_HEIGHT};
background: ${({ themeStyles }) => themeStyles.panel.backgroundColor};
border-top: 2px solid ${({ themeStyles }) => themeStyles.panel.borderColor};
border-top: ${BORDER_SIZE} solid ${({ themeStyles }) => themeStyles.panel.borderColor};
`;
export const ScrollableContainer = styled.div`

export const ScrollableContainer = styled.div<{ themeStyles?: ITheme; isMobileSize?: boolean }>`
display: flex;
height: 100%;
padding: 0 0.625rem;
height: calc(${PAGES_CONTAINER_HEIGHT} - ${SCROLL_SIZE} - ${BORDER_SIZE});
align-items: center;
overflow-x: auto;
width: auto;
white-space: nowrap;
overflow-y: hidden;
padding: 0.5rem 0.625rem 0 0.625rem;
scrollbar-gutter: stable;
`;

export const Card = styled.div<{ themeStyles: ITheme; selected?: boolean }>`
box-sizing: border-box;
width: 5rem;
Expand Down
24 changes: 17 additions & 7 deletions src/components/pagesPanel/Pages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
useTheme,
} from '@chili-publish/grafx-shared-components';
import { ScrollableContainer, Card, Container } from './Pages.styles';
import { PREVIEW_FALLBACK } from '../../utils/constants';
import { BORDER_SIZE, PAGES_CONTAINER_HEIGHT, PREVIEW_FALLBACK } from '../../utils/constants';
import { PageSnapshot } from '../../types/types';
import { PreviewCardBadge } from './PreviewCardBadge';
import { useAttachArrowKeysListener } from './useAttachArrowKeysListener';

interface PagesProps {
pages: Page[];
Expand All @@ -25,10 +26,6 @@
const [pageSnapshots, setPageSnapshots] = useState<PageSnapshot[]>([]);
const isMobileSize = useMobileSize();

const handleSelectPage = async (pageId: string) => {
await window.StudioUISDK.page.select(pageId);
};

const getPagesSnapshot = useCallback(async (ids: string[]) => {
const snapArray = ids.map((id) =>
window.SDK.page.getSnapshot(id).then((snapshot) => ({
Expand All @@ -41,6 +38,14 @@
return awaitedArray as PageSnapshot[];
}, []);

/**
* by attaching listeners here and not in ShortcutProvider.tsx,
* 'pages' prop that gets populated via 'onPagesChanged' subscriber,
* will not trigger rerenders of ShortcutProvider's children,
* causing multiple query refectch in useMediaDetails
*/
const { handleSelectPage } = useAttachArrowKeysListener({ pages, activePageId });

useEffect(() => {
if (pages?.length && !pageSnapshots.length) {
getPagesSnapshot(pages.map((i) => i.id));
Expand Down Expand Up @@ -77,12 +82,17 @@
return () => {
clearTimeout(timeoutId);
};
}, [pagesToRefresh, setPagesToRefresh, getPagesSnapshot]);

Check warning on line 85 in src/components/pagesPanel/Pages.tsx

View workflow job for this annotation

GitHub Actions / build (20)

React Hook useEffect has a missing dependency: 'pages'. Either include it or remove the dependency array. If 'setPageSnapshots' needs the current value of 'pages', you can also switch to useReducer instead of useState and read 'pages' in the reducer

return (
<Container themeStyles={theme} isMobileSize={isMobileSize}>
<ScrollbarWrapper invertScrollbarColors>
<ScrollableContainer>
<ScrollbarWrapper
height={`calc(${PAGES_CONTAINER_HEIGHT} - ${BORDER_SIZE})`}
enableOverflowX
enableOverflowY={false}
smereuta marked this conversation as resolved.
Show resolved Hide resolved
scrollbarHeight={!isMobileSize ? '0.875rem' : '0'}
>
<ScrollableContainer isMobileSize={isMobileSize}>
{!!pages?.length &&
pages.map((item, index) => (
<PreviewCardBadge badgeNumber={index + 1} key={`badge-${item.id}`}>
Expand Down
60 changes: 60 additions & 0 deletions src/components/pagesPanel/useAttachArrowKeysListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useGetIframeAsync } from '@chili-publish/grafx-shared-components';
import { Page } from '@chili-publish/studio-sdk';
import { useCallback, useEffect, useState } from 'react';

export const useAttachArrowKeysListener = ({ pages, activePageId }: { pages: Page[]; activePageId: string | null }) => {
const iframe = useGetIframeAsync({ containerId: 'studio-ui-chili-editor' })?.contentWindow;

const [selectedPageIndex, setSelectedPageIndex] = useState<number>(pages.findIndex((i) => i.id === activePageId));
smereuta marked this conversation as resolved.
Show resolved Hide resolved

const handleSelectPage = async (pageId: string) => {
await window.StudioUISDK.page.select(pageId);
};
const handleOnArrowKeyDown = useCallback(
async (event: KeyboardEvent) => {
const formElements = ['INPUT', 'TEXTAREA', 'SELECT', 'OPTION'];
if (formElements.includes((event.target as HTMLElement).tagName)) {
return;
}
switch (event.key) {
case 'ArrowLeft': {
let index = selectedPageIndex - 1;
setSelectedPageIndex((prevIndex) => {
index = prevIndex > 0 ? prevIndex - 1 : prevIndex;
return index;
});
handleSelectPage(pages[index].id);
break;
}
case 'ArrowRight': {
let index = selectedPageIndex + 1;
setSelectedPageIndex((prevIndex) => {
index = prevIndex + 1 < pages.length ? prevIndex + 1 : prevIndex;
return index;
});
handleSelectPage(pages[index].id);
break;
}
default:
break;
}
},
[selectedPageIndex, pages],
);

useEffect(() => {
const addShortcutListeners = () => {
document.addEventListener('keydown', handleOnArrowKeyDown);
iframe?.addEventListener('keydown', handleOnArrowKeyDown);
};

addShortcutListeners();

return () => {
document.removeEventListener('keydown', handleOnArrowKeyDown);
iframe?.removeEventListener('keydown', handleOnArrowKeyDown);
};
}, [handleOnArrowKeyDown, iframe]);

return { handleSelectPage };
};
3 changes: 3 additions & 0 deletions src/components/variables/MobileVariablesTray.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ function MobileVariablesPanel(props: VariablesPanelProps) {
overflow: ${isVariablesListOpen ? 'auto' : 'hidden'};
${contentType === ContentType.IMAGE_PANEL && `padding-bottom: 0`};
${isDataSourcePanelOpen && dataSourceTrayStyles}
&::-webkit-scrollbar {
width: 0;
}
`}
>
<VariablesContainer height={showImagePanel ? imagePanelHeight : undefined}>
Expand Down
7 changes: 4 additions & 3 deletions src/tests/components/dataSource/DataSourceModal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,16 @@ describe('DataSourceModal test', () => {
expect(dataRowsTable).toBeInTheDocument();
});

expect(screen.getByText('Row 1')).toBeInTheDocument();
expect(screen.getByDisplayValue('1 | Joe | 15')).toBeInTheDocument();

await act(async () => {
await user.keyboard('[ArrowDown]');
});

expect(screen.getByText('Row 1')).toBeInTheDocument();
expect(screen.getByDisplayValue('1 | Joe | 15')).toBeInTheDocument();
await act(async () => {
await user.keyboard('[Enter]');
});

expect(screen.queryByRole('table')).not.toBeInTheDocument();
expect(screen.getByText('Row 2')).toBeInTheDocument();
expect(screen.getByDisplayValue('2 | John | 18')).toBeInTheDocument();
Expand Down
4 changes: 4 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export const APP_WRAPPER_ID = 'studio-ui-application';
export const PREVIEW_FALLBACK = 'https://studio-cdn.chiligrafx.com/shared/assets/preview-fallback-padded.svg';
export const SESSION_USER_INTEFACE_ID_KEY = 'userInterfaceId';

export const PAGES_CONTAINER_HEIGHT = '7.5rem';
export const BORDER_SIZE = '0.125rem'; // 2px;
export const SCROLL_SIZE = '0.875rem';
7 changes: 3 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1307,10 +1307,9 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==

"@chili-publish/grafx-shared-components@^0.88.7":
version "0.88.7"
resolved "https://npm.pkg.github.com/download/@chili-publish/grafx-shared-components/0.88.7/45252dbd33710f882c1aaf10261388490fc1d74c#45252dbd33710f882c1aaf10261388490fc1d74c"
integrity sha512-zTI0QC4UevhkkHvKnfpSFjGYpb7fwd3Fd340CmRJ1zCTWqjmpgijgLy/guotXlGqlXMabEwf4dlaqu8Sg+J4Ew==
"@chili-publish/grafx-shared-components@https://stgrafxstudiodevpublic.blob.core.windows.net/grafx-shared-components/dev-shared-components/466/grafx-shared-components.tgz":
version "0.88.9"
resolved "https://stgrafxstudiodevpublic.blob.core.windows.net/grafx-shared-components/dev-shared-components/466/grafx-shared-components.tgz#3291b20d794f934a49d5059a58a6b0015cf1150f"

"@chili-publish/studio-sdk@^1.17.2-rc.2":
version "1.17.2-rc.2"
Expand Down
Loading