mirror of
https://github.com/suitenumerique/docs.git
synced 2026-08-17 21:25:43 +02:00
💄(frontend) improve ui/ux before release
Following the recommendations of the design team, we lightly improved some UI/UX elements to be more consistent and user-friendly before the next release. It includes the following changes: - add a background to the grid - add a fadein to the header buttons - reduce the generic size icon - add a title to the doc item
This commit is contained in:
@@ -142,7 +142,7 @@
|
||||
"icon": {
|
||||
"src": "/assets/icon-docs.svg",
|
||||
"style": {
|
||||
"width": "40px",
|
||||
"width": "36px",
|
||||
"height": "auto"
|
||||
},
|
||||
"alt": "",
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { PropsWithChildren, useEffect, useState } from 'react';
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
|
||||
export const showEffect = `
|
||||
transform: scaleY(1);
|
||||
opacity: 1;
|
||||
@@ -9,3 +12,56 @@ export const hideEffect = `
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
`;
|
||||
|
||||
const fadeIn = keyframes`
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const fadeOut = keyframes`
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const FadeItem = styled.div<{ $isVisible: boolean }>`
|
||||
display: flex;
|
||||
animation: ${({ $isVisible }) => ($isVisible ? fadeIn : fadeOut)} 0.2s ease
|
||||
forwards;
|
||||
`;
|
||||
|
||||
export const FadeComponent = ({
|
||||
children,
|
||||
isVisible,
|
||||
}: PropsWithChildren<{ isVisible: boolean }>) => {
|
||||
const [isGroupMounted, setIsGroupMounted] = useState(isVisible);
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisible) {
|
||||
setIsGroupMounted(true);
|
||||
}
|
||||
}, [isVisible]);
|
||||
|
||||
const handleFadeOutEnd = () => {
|
||||
if (!isVisible) {
|
||||
setIsGroupMounted(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (!isGroupMounted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<FadeItem $isVisible={isVisible} onAnimationEnd={handleFadeOutEnd}>
|
||||
{children}
|
||||
</FadeItem>
|
||||
);
|
||||
};
|
||||
|
||||
+1
@@ -100,6 +100,7 @@ export const SimpleDocItem = ({
|
||||
$weight="500"
|
||||
$css={ItemTextCss}
|
||||
data-testid="doc-title"
|
||||
title={docTitle}
|
||||
>
|
||||
{docTitle}
|
||||
</Text>
|
||||
|
||||
@@ -90,10 +90,9 @@ export const DocsGrid = ({
|
||||
<DocsGridLoader isLoading={isRefetching || loading || isImportPending} />
|
||||
<Card
|
||||
data-testid="docs-grid"
|
||||
$height="100%"
|
||||
$width="100%"
|
||||
$css={css`
|
||||
border: none;
|
||||
border: 1px solid var(--c--contextuals--border--surface--primary);
|
||||
${isDragOver
|
||||
? `
|
||||
border: 2px dashed var(--c--contextuals--border--semantic--brand--primary);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { FadeComponent } from '@/components/Effect';
|
||||
import { CardFloatingBar, FloatingBar } from '@/components/FloatingBar';
|
||||
import { DocSearchButtonModal } from '@/features/docs/doc-search/components/DocSearchButtonModal';
|
||||
import { LeftPanelCollapseButton } from '@/features/left-panel/components/LeftPanelCollapseButton';
|
||||
@@ -13,19 +14,21 @@ export const HeaderFloatingBar = () => {
|
||||
const { t } = useTranslation();
|
||||
const { isPanelOpen } = useLeftPanelStore();
|
||||
|
||||
const isVisible = (isTablet && !isPanelOpen) || isMobile;
|
||||
|
||||
return (
|
||||
<FloatingBar $align="center">
|
||||
{isTablet && (
|
||||
<LeftPanelCollapseButton ariaLabel={t('Toggle left panel')} />
|
||||
)}
|
||||
{(isTablet && !isPanelOpen) || isMobile ? (
|
||||
<>
|
||||
<HeaderIcon />
|
||||
<CardFloatingBar>
|
||||
<DocSearchButtonModal size="small" color="neutral" />
|
||||
</CardFloatingBar>
|
||||
</>
|
||||
) : null}
|
||||
<FadeComponent isVisible={isVisible}>
|
||||
<HeaderIcon />
|
||||
</FadeComponent>
|
||||
<FadeComponent isVisible={isVisible}>
|
||||
<CardFloatingBar>
|
||||
<DocSearchButtonModal size="small" color="neutral" />
|
||||
</CardFloatingBar>
|
||||
</FadeComponent>
|
||||
</FloatingBar>
|
||||
);
|
||||
};
|
||||
|
||||
+4
-2
@@ -1,6 +1,7 @@
|
||||
import { Button } from '@gouvfr-lasuite/cunningham-react';
|
||||
|
||||
import { Text } from '@/components';
|
||||
import { FadeComponent } from '@/components/Effect';
|
||||
import { CardFloatingBar } from '@/components/FloatingBar';
|
||||
|
||||
import LeftPanelIcon from '../assets/left-panel.svg';
|
||||
@@ -27,15 +28,16 @@ export const LeftPanelCollapseButton = ({
|
||||
icon={<LeftPanelIcon width={24} height={24} aria-hidden="true" />}
|
||||
data-testid="floating-bar-toggle-left-panel"
|
||||
></Button>
|
||||
{buttonTitle && (
|
||||
<FadeComponent isVisible={!!buttonTitle}>
|
||||
<Text
|
||||
$size="sm"
|
||||
$weight={700}
|
||||
$color="var(--c--globals--colors--gray-1000)"
|
||||
$padding={{ right: '2xs' }}
|
||||
>
|
||||
{buttonTitle}
|
||||
</Text>
|
||||
)}
|
||||
</FadeComponent>
|
||||
</CardFloatingBar>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { PropsWithChildren } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
import { Box, BoxProps } from '@/components';
|
||||
import { Box, BoxType } from '@/components';
|
||||
import { LeftPanel, ResizableLeftPanel } from '@/features/left-panel';
|
||||
import { RightPanel } from '@/features/right-panel/components/RightPanel';
|
||||
import { DocEditorSkeleton, Skeleton } from '@/features/skeletons';
|
||||
@@ -12,11 +12,15 @@ import { usePanelCoordination } from './usePanelCoordination';
|
||||
|
||||
type MainLayoutProps = {
|
||||
enableResizablePanel?: boolean;
|
||||
propsLayout?: BoxType;
|
||||
propsContent?: BoxType;
|
||||
};
|
||||
|
||||
export function MainLayout({
|
||||
children,
|
||||
enableResizablePanel = false,
|
||||
propsLayout,
|
||||
propsContent,
|
||||
}: PropsWithChildren<MainLayoutProps>) {
|
||||
return (
|
||||
<Box
|
||||
@@ -24,42 +28,50 @@ export function MainLayout({
|
||||
$direction="row"
|
||||
$width="100%"
|
||||
$height="100dvh"
|
||||
{...propsLayout}
|
||||
>
|
||||
<MainLayoutContent enableResizablePanel={enableResizablePanel}>
|
||||
<MainLayoutContent
|
||||
enableResizablePanel={enableResizablePanel}
|
||||
{...propsContent}
|
||||
>
|
||||
{children}
|
||||
</MainLayoutContent>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export interface MainLayoutContentProps {
|
||||
export interface MainLayoutContentProps extends BoxType {
|
||||
enableResizablePanel: boolean;
|
||||
}
|
||||
|
||||
export function MainLayoutContent({
|
||||
children,
|
||||
enableResizablePanel,
|
||||
...props
|
||||
}: PropsWithChildren<MainLayoutContentProps>) {
|
||||
if (enableResizablePanel) {
|
||||
return <MainResizableLayout>{children}</MainResizableLayout>;
|
||||
return <MainResizableLayout {...props}>{children}</MainResizableLayout>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<LeftPanel />
|
||||
<MainContent>{children}</MainContent>
|
||||
<MainContent {...props}>{children}</MainContent>
|
||||
<RightPanel />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const MainResizableLayout = ({ children }: PropsWithChildren) => {
|
||||
const MainResizableLayout = ({
|
||||
children,
|
||||
...props
|
||||
}: PropsWithChildren<BoxType>) => {
|
||||
usePanelCoordination();
|
||||
|
||||
return (
|
||||
<ResizableLeftPanel>
|
||||
<Box $direction="row" $width="100%" $position="relative">
|
||||
<MainContent $flex="auto" $padding="0">
|
||||
<MainContent $flex="auto" $padding="0" {...props}>
|
||||
{children}
|
||||
</MainContent>
|
||||
<RightPanel />
|
||||
@@ -71,7 +83,7 @@ const MainResizableLayout = ({ children }: PropsWithChildren) => {
|
||||
export const MainContent = ({
|
||||
children,
|
||||
...props
|
||||
}: PropsWithChildren<BoxProps>) => {
|
||||
}: PropsWithChildren<BoxType>) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
|
||||
@@ -35,7 +35,15 @@ const Page: NextPageWithLayout = () => {
|
||||
};
|
||||
|
||||
Page.getLayout = function getLayout(page: ReactElement) {
|
||||
return <MainLayout>{page}</MainLayout>;
|
||||
return (
|
||||
<MainLayout
|
||||
propsContent={{
|
||||
$background: 'var(--c--contextuals--background--surface--tertiary)',
|
||||
}}
|
||||
>
|
||||
{page}
|
||||
</MainLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default Page;
|
||||
|
||||
Reference in New Issue
Block a user