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(wallet): rebrand top bar #1775

Merged
merged 11 commits into from
Aug 14, 2024
1 change: 0 additions & 1 deletion apps/wallet/src/ui/app/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export * from './iota-apps/IotaApp';
export * from './ledger';
export * from './loading';
export * from './loading/LoadingIndicator';
export * from './logo';
export * from './menu';
export * from './navigation';
export * from './network-selector';
Expand Down
30 changes: 0 additions & 30 deletions apps/wallet/src/ui/app/components/logo/index.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,26 @@
// Modifications Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { Close, Settings } from '@iota/ui-icons';
import { useMenuIsOpen, useNextMenuUrl } from '_components';
import { ButtonOrLink } from '_src/ui/app/shared/utils/ButtonOrLink';
import { HamburgerOpen24 as HamburgerOpenIcon, Settings24 as SettingsIcon } from '@iota/icons';
import { cx } from 'class-variance-authority';

import { useMenuIsOpen, useNextMenuUrl } from '_components';

export function WalletSettingsButton() {
const isOpen = useMenuIsOpen();
const menuUrl = useNextMenuUrl(!isOpen, '/');
const IconComponent = isOpen ? HamburgerOpenIcon : SettingsIcon;
const IconComponent = isOpen ? Close : Settings;

return (
<ButtonOrLink
className={cx(
'hover:text-hero-dark ml-auto flex cursor-pointer appearance-none items-center justify-center border-none bg-transparent',
'hover:text-hero-dark ml-auto flex cursor-pointer appearance-none items-center justify-center border-none bg-transparent p-xs text-neutral-10 [&_svg]:h-5 [&_svg]:w-5',
{ 'text-steel': !isOpen, 'text-gray-90': isOpen },
)}
aria-label={isOpen ? 'Close settings menu' : 'Open settings menu'}
to={menuUrl}
>
<IconComponent className="h-6 w-6" />
<IconComponent />
</ButtonOrLink>
);
}
2 changes: 1 addition & 1 deletion apps/wallet/src/ui/app/components/navigation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function Navigation() {
];
const [activeRouteId, setActiveRouteId] = useState<string>(NAVBAR_ITEMS[0].id);
return (
<div className="sticky bottom-0 w-full shrink-0 rounded-tl-md rounded-tr-md border-b-0 bg-white">
<div className="sticky bottom-0 w-full shrink-0 border-b-0 bg-white">
<Navbar
items={NAVBAR_ITEMS}
activeId={activeRouteId}
Expand Down
8 changes: 6 additions & 2 deletions apps/wallet/src/ui/app/pages/accounts/AddAccountPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ import {
ImageType,
CardActionType,
} from '@iota/apps-ui-kit';
import { AccountsFormType, useAccountsFormContext, ConnectLedgerModal } from '_components';
import {
AccountsFormType,
useAccountsFormContext,
ConnectLedgerModal,
PageTemplate,
} from '_components';
import { getLedgerConnectionErrorMessage } from '../../helpers/errorMessages';
import { useAppSelector } from '../../hooks';
import { useCreateAccountsMutation } from '../../hooks/useCreateAccountMutation';
import { AppType } from '../../redux/slices/app/AppType';
import { Create, ImportPass, Key, Seed, Ledger } from '@iota/ui-icons';
import { PageTemplate } from '../../components/PageTemplate';

async function openTabWithSearchParam(searchParam: string, searchParamValue: string) {
const currentURL = new URL(window.location.href);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { useNavigate } from 'react-router-dom';

import {
AccountsFormType,
ImportPrivateKeyForm,
PageTemplate,
useAccountsFormContext,
} from '../../components/accounts/AccountsFormContext';
import { ImportPrivateKeyForm } from '../../components/accounts/ImportPrivateKeyForm';
import { PageTemplate } from '../../components/PageTemplate';
} from '_components';

export function ImportPrivateKeyPage() {
const navigate = useNavigate();
Expand Down
20 changes: 6 additions & 14 deletions apps/wallet/src/ui/app/shared/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,24 @@

import { type Network } from '@iota/iota-sdk/client';
import { type ReactNode } from 'react';
import { Link } from 'react-router-dom';

import { Logo } from '_components';

interface HeaderProps {
network: Network;
middleContent?: ReactNode;
rightContent?: ReactNode;
leftContent?: ReactNode;
}

/**
* General page header that can render arbitrary content where the content
* located in the middle of the header is centered and has a capped width
*/
export function Header({ network, middleContent, rightContent }: HeaderProps) {
export function Header({ network, leftContent, middleContent, rightContent }: HeaderProps) {
return (
<header className="grid grid-cols-header items-center gap-3 px-3 py-2">
<div>
<Link to="/" className="text-gray-90 no-underline">
<Logo network={network} />
</Link>
</div>
{middleContent && <div className="col-start-2 overflow-hidden">{middleContent}</div>}
{rightContent && (
<div className="col-start-3 mr-1 justify-self-end">{rightContent}</div>
)}
<header className="flex flex-row items-center justify-between bg-neutral-100 px-md py-xs">
{leftContent && <div>{leftContent}</div>}
{middleContent && <div className="overflow-hidden">{middleContent}</div>}
{rightContent && <div>{rightContent}</div>}
</header>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import { AppType } from '../../redux/slices/app/AppType';
import DappStatus from '../dapp-status';
import { Header } from '../header/Header';
import { Toaster } from '../toaster';
import { IotaLogoMark, Ledger } from '@iota/ui-icons';
import { useActiveAccount } from '../../hooks/useActiveAccount';
import { Link } from 'react-router-dom';
import { formatAddress } from '@iota/iota-sdk/utils';
import { isLedgerAccountSerializedUI } from '_src/background/accounts/LedgerAccount';

export const PageMainLayoutContext = createContext<HTMLDivElement | null>(null);

Expand All @@ -29,25 +34,34 @@ export function PageMainLayout({
}: PageMainLayoutProps) {
const network = useAppSelector(({ app: { network } }) => network);
const appType = useAppSelector((state) => state.app.appType);
const activeAccount = useActiveAccount();
const isFullScreen = appType === AppType.Fullscreen;
const [titlePortalContainer, setTitlePortalContainer] = useState<HTMLDivElement | null>(null);
const isLedgerAccount = activeAccount && isLedgerAccountSerializedUI(activeAccount);

return (
<div
className={cn(
'flex max-h-full w-full flex-1 flex-col flex-nowrap items-stretch justify-center overflow-hidden bg-gradients-graph-cards',
'flex max-h-full w-full flex-1 flex-col flex-nowrap items-stretch justify-center overflow-hidden',
isFullScreen ? 'rounded-xl' : '',
)}
>
<Header
network={network}
leftContent={
<LeftContent
account={activeAccount?.address}
isLedgerAccount={isLedgerAccount}
isLocked={activeAccount?.isLocked}
/>
}
middleContent={
dappStatusEnabled ? <DappStatus /> : <div ref={setTitlePortalContainer} />
}
rightContent={topNavMenuEnabled ? <WalletSettingsButton /> : undefined}
/>
<div className="relative flex flex-grow flex-col flex-nowrap overflow-hidden rounded-t-xl shadow-wallet-content">
<div className="flex flex-grow flex-col flex-nowrap overflow-y-auto overflow-x-hidden rounded-t-xl bg-white">
<div className="relative flex flex-grow flex-col flex-nowrap overflow-hidden">
<div className="flex flex-grow flex-col flex-nowrap overflow-y-auto overflow-x-hidden bg-neutral-100">
<main
className={cn('flex w-full flex-grow flex-col', {
'p-5': bottomNavEnabled,
Expand All @@ -57,11 +71,39 @@ export function PageMainLayout({
<ErrorBoundary>{children}</ErrorBoundary>
</PageMainLayoutContext.Provider>
</main>
{bottomNavEnabled ? <Navigation /> : null}
<Toaster bottomNavEnabled={bottomNavEnabled} />
</div>
{topNavMenuEnabled ? <MenuContent /> : null}
</div>
{bottomNavEnabled ? <Navigation /> : null}
</div>
);
}

function LeftContent({
account,
isLedgerAccount,
isLocked,
}: {
account: string | undefined;
isLedgerAccount: boolean | null;
isLocked?: boolean;
}) {
const backgroundColor = isLocked ? 'bg-neutral-90' : 'bg-primary-30';
return (
<Link
to="/accounts/manage"
className="flex flex-row items-center gap-sm p-xs text-pink-200 no-underline"
>
<div
className={cn(
'rounded-full p-1 text-neutral-100 [&_svg]:h-5 [&_svg]:w-5',
backgroundColor,
)}
>
{isLedgerAccount ? <Ledger /> : <IotaLogoMark />}
</div>
<span className="text-title-sm text-neutral-10">{formatAddress(account || '')}</span>
</Link>
);
}
Loading