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

feat(container): add animations to pnr #14691

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const node: Node = {
const props: Props = {
node: node,
isSelected: false,
isLoading: false
};

const id: string = "assistance-link-item";
Expand All @@ -51,7 +52,7 @@ vi.mock('../SidebarLink', () => ({

const renderAssistanceLinkItem = (props: Props) => {
return render(
<AssistanceLinkItem node={props.node} isSelected={props.isSelected} />,
<AssistanceLinkItem node={props.node} isSelected={props.isSelected} isLoading={props.isLoading} />,
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@ import { Node } from '../navigation-tree/node';
import { FunctionComponent } from 'react';
import style from '../style.module.scss';
import SidebarLink from '../SidebarLink';
import { OsdsSkeleton } from '@ovhcloud/ods-components/react';

export type Props = {
node: Node;
isSelected: boolean;
isLoading: boolean;
}

export const AssistanceLinkItem: FunctionComponent<Props> = ({ node, isSelected }) => {
export const AssistanceLinkItem: FunctionComponent<Props> = ({ node, isSelected, isLoading }) => {
return (
<li className={`flex align-items-center ${isSelected ? style.sidebar_menu_items_selected : ''} ${style.sidebar_menu_items}`} role="menuitem" data-testid="assistance-link-item">
<SidebarLink
<li className={`flex align-items-center whitespace-nowrap ${isSelected ? style.sidebar_menu_items_selected : ''} ${style.sidebar_menu_items}`} role="menuitem" data-testid="assistance-link-item">
{isLoading ? <OsdsSkeleton randomized className='mx-8' /> : <SidebarLink
handleOnClick={node.onClick}
node={node}
/>
/>}
</li>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const props: AssistanceProps = {
nodeTree: assistanceTree,
isShort: false,
selectedNode: null,
isLoading: false
};

const renderAssistanceSidebar = (props: AssistanceProps) => {
Expand All @@ -49,6 +50,7 @@ const renderAssistanceSidebar = (props: AssistanceProps) => {
nodeTree={props.nodeTree}
selectedNode={props.selectedNode}
isShort={props.isShort}
isLoading={props.isLoading}
/>,
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ export interface AssistanceProps {
nodeTree?: Node;
isShort: boolean;
selectedNode: Node;
isLoading: boolean;
}

const AssistanceSidebar: React.FC<ComponentProps<AssistanceProps>> = ({
nodeTree,
selectedNode,
isShort
isShort,
isLoading
}): JSX.Element => {
const { t } = useTranslation('sidebar');
const shell = useShell();
Expand All @@ -32,7 +34,7 @@ const AssistanceSidebar: React.FC<ComponentProps<AssistanceProps>> = ({
const urls = useURL(environment);
const trackingPlugin = shell.getPlugin('tracking');
const isEUOrCA = ['EU', 'CA'].includes(environment.getRegion());
const { closeNavigationSidebar } = useProductNavReshuffle();
const { closeNavigationSidebar, setIsAnimated } = useProductNavReshuffle();

useEffect(() => {
nodeTree.children.forEach((node: Node) => {
Expand Down Expand Up @@ -93,6 +95,7 @@ const AssistanceSidebar: React.FC<ComponentProps<AssistanceProps>> = ({
variant={ODS_BUTTON_VARIANT.ghost}
size={ODS_BUTTON_SIZE.md}
title={t('sidebar_assistance_title')}
onClick={() => setIsAnimated(true)}
contrasted
>
<OsdsIcon
Expand All @@ -111,14 +114,15 @@ const AssistanceSidebar: React.FC<ComponentProps<AssistanceProps>> = ({
return (
<ul className="mt-auto pb-3 flex-none" id="useful-links" role="menu" data-testid="assistance-sidebar">
<li className="assistance_header px-3 mb-3">
<h2 className="flex justify-between">
<h2 className="flex justify-between whitespace-nowrap">
<span>{t('sidebar_assistance_title')}</span>
</h2>
</li>
{nodeTree.children.map((node: Node) => (
<AssistanceLinkItem
key={`assistance_${node.id}`}
node={node}
isLoading={isLoading}
isSelected={node.id === selectedNode?.id}
/>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import style from './style.module.scss';
import SidebarLinkTag from './SidebarLinkTag';
import { Node } from './navigation-tree/node';
import StaticLink from '@/container/nav-reshuffle/sidebar/StaticLink';
import { OsdsIcon } from '@ovhcloud/ods-components/react';
import { OsdsIcon, OsdsSkeleton, OsdsSpinner } from '@ovhcloud/ods-components/react';
import {
ODS_ICON_NAME,
ODS_ICON_SIZE,
ODS_SKELETON_SIZE,
ODS_SPINNER_SIZE,
} from '@ovhcloud/ods-components';
import { SvgIconWrapper } from '@ovh-ux/ovh-product-icons/utils/SvgIconWrapper';

Expand All @@ -19,6 +21,7 @@ export type SidebarLinkProps = {
handleOnEnter?(node: Node): void;
id?: string;
isShortText?: boolean;
isLoading?: boolean;
};

const SidebarLink: React.FC<ComponentProps<SidebarLinkProps>> = ({
Expand All @@ -29,6 +32,7 @@ const SidebarLink: React.FC<ComponentProps<SidebarLinkProps>> = ({
handleOnEnter = () => { },
id = '',
isShortText = false,
isLoading = false,
}: SidebarLinkProps): JSX.Element => {
const { t } = useTranslation('sidebar');

Expand All @@ -44,7 +48,9 @@ const SidebarLink: React.FC<ComponentProps<SidebarLinkProps>> = ({
/>
) : (
<button
className={`${style['button-as-div']} relative`}
className={`${style.button_as_div} ${
isShortText ? style.button_as_div_short : ''
} relative`}
title={t(node.translation)}
onKeyUp={(e) => {
if (e.key === 'Enter') {
Expand All @@ -56,9 +62,12 @@ const SidebarLink: React.FC<ComponentProps<SidebarLinkProps>> = ({
data-testid={id}
role="button"
>
<span className='flex gap-2 align-items-center'>
<SvgIconWrapper name={node.svgIcon} height={32} width={32} className='p-1 fill-white block' />
{!isShortText && <span>{t(node.translation)}</span>}
<span className='flex gap-2 align-items-center w-full whitespace-nowrap'>
{(!isShortText || !isLoading) && <SvgIconWrapper name={node.svgIcon} height={32} width={32} className={`p-1 fill-white transition-all duration-200O shrink-0 ${isLoading && isShortText ? 'hidden' : 'block'}`} />}
{isShortText && isLoading &&
<OsdsSpinner className={`h-[32px] w-[32px] transition-all duration-200O shrink-0`} size={ODS_SPINNER_SIZE.sm} contrasted />
}
{!isShortText && (isLoading ? <OsdsSkeleton inline={true} className='mx-2' size={ODS_SKELETON_SIZE.xs} randomized /> : <span>{t(node.translation)}</span>)}
</span>
<span className="flex justify-end align-items-center">
{(count as number) > 0 && (
Expand All @@ -76,7 +85,7 @@ const SidebarLink: React.FC<ComponentProps<SidebarLinkProps>> = ({
) : null}
{!isShortText && <SidebarLinkTag node={node} />}
</span>
</button >
</button>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export const PublicCloudPanel: React.FC<ComponentProps<
)}
{selectedPciProject && (
<button
className={`d-flex ${style['button-as-div']} ${style.sidebar_clipboard}`}
className={`d-flex ${style.button_as_div} ${style.sidebar_clipboard}`}
title={t('sidebar_clipboard_copy')}
onClick={() =>
navigator.clipboard.writeText(selectedPciProject.project_id)
Expand Down
aottr marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import style from './style.module.scss';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Node } from '@/container/nav-reshuffle/sidebar/navigation-tree/node';
import {
Expand All @@ -19,6 +19,7 @@ interface SubTreeProps {
handleCloseSideBar(): void;
handleOnSubMenuClick(node: Node): void;
selectedNode: Node;
open: boolean;
}

const SubTree = ({
Expand All @@ -27,16 +28,25 @@ const SubTree = ({
handleOnSubMenuClick,
selectedNode,
handleCloseSideBar,
open
}: SubTreeProps): JSX.Element => {
const { t } = useTranslation('sidebar');
const { isMobile } = useProductNavReshuffle();
const { isMobile, isAnimated } = useProductNavReshuffle();
const [isOpen, setIsOpen] = useState(false);

const [focusOnLast, setFocusOnLast] = useState<boolean>(false);
const lastElement = getLastElement(rootNode);

useEffect(() => {
const timeOut = setTimeout(() => {
setIsOpen(open);
}, 10);
return () => clearTimeout(timeOut);
}, [open])

return (
<div
className={style.subtree_content}
className={`${style.subtree_content} ${isOpen ? style.subtree_content_open : style.subtree_content_close} ${isAnimated && style.subtree_content_animated}`}
onBlur={(e: any) => {
const id = e.relatedTarget?.id.replace('-link', '');
if (id === lastElement.id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,46 @@
@import '@ovh-ux/ui-kit/dist/scss/tokens/_globals';

.subtree {
width: 100%;
height: 100%;
background-color: rgba($p-500, 0.50);
position: fixed;
top: 0;
left: 20rem;
z-index: 901;
overflow-y: auto;
&_content {
display: flex;
flex-flow: column;
justify-content: start;
background: $p-800;
height: auto;
min-height: 100%;
width: 20rem;
width: 0rem;
overflow-y: auto;

transform: scaleX(0);
transform-origin: 0% 50%;
opacity: 0;

&_animated {
transition: transform 0.3s ease-in, opacity 0.3s ease-in,
width 0s ease-out 0.3s;

&_open {
transition: transform 0.3s ease-in 0s, opacity 0.3s ease-in 0s,
width 0s ease-out 0s;
}

&_close {
transition: transform 0.3s ease-in 0s, opacity 0.3s ease-in 0s,
width 0s ease-out 0s;
}
}

&_open {
transform: scaleX(1);
opacity: 1;
width: 20rem;
}

&_close {
transform: scaleX(0);
opacity: 0;
width: 20rem;
}
}
&_list {
min-height: 28.125rem;
Expand All @@ -32,7 +55,7 @@
width: 100%;
}
}
&_back_btn{
&_back_btn {
display: none;
height: 2.5rem;
background-color: $p-500;
Expand All @@ -44,12 +67,12 @@
padding: 0 0.625em;
width: 100%;
}
&_section_title{
&_section_title {
color: $p-200 !important;
text-transform: uppercase;
font-size: 1rem !important;
}
&_section{
&_section {
&:after {
content: '';
margin: 0 1rem;
Expand All @@ -72,21 +95,27 @@
border: none;
}

&_submenu_items, &_submenu_items_selected {
a, button {
&_submenu_items,
&_submenu_items_selected {
a,
button {
padding: 0 1rem;
}
}

&_submenu_items {
a:hover, a:focus, button:hover, button:focus {
a:hover,
a:focus,
button:hover,
button:focus {
background-color: darken($p-800, 5);
text-decoration: none;
}
}

&_submenu_items_selected {
a, button {
a,
button {
background-color: darken($p-800, 5);
text-decoration: none !important;
}
Expand All @@ -103,9 +132,14 @@
left: 0;
width: 100%;
padding-top: 2.75rem;
transition: none;

&_open, &_close {
transition: none;
}
}
&_back_btn {
display: flex;
}
}
}
}
Loading
Loading