handleSetAsideExpanded(false)}
- onDone={() => handleSetAsideExpanded(false)}
- input={getContact(contactId)}
- />
- >
- );
-};
-
-export default AddContact;
diff --git a/packages/apps/dev-wallet/src/Components/Aside/views/Error.tsx b/packages/apps/dev-wallet/src/Components/Aside/views/Error.tsx
deleted file mode 100644
index acdd038e90..0000000000
--- a/packages/apps/dev-wallet/src/Components/Aside/views/Error.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const Error = () => {
- return There was an error loading the view
;
-};
-
-export default Error;
diff --git a/packages/apps/dev-wallet/src/Components/Aside/views/KeySource.tsx b/packages/apps/dev-wallet/src/Components/Aside/views/KeySource.tsx
deleted file mode 100644
index df71a04bc8..0000000000
--- a/packages/apps/dev-wallet/src/Components/Aside/views/KeySource.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { useHDWallet } from '@/modules/key-source/hd-wallet/hd-wallet';
-import { keySourceManager } from '@/modules/key-source/key-source-manager';
-import { WebAuthnService } from '@/modules/key-source/web-authn/webauthn';
-import { useWallet } from '@/modules/wallet/wallet.hook';
-
-import { AddKeySourceForm } from '@/pages/keys/Components/AddKeySourceForm';
-import { Notification, Stack } from '@kadena/kode-ui';
-import { useLayout } from '@kadena/kode-ui/patterns';
-import { useEffect, useState } from 'react';
-
-const KeySource = () => {
- const { handleSetAsideExpanded, setAsideTitle } = useLayout();
- const { keySources, profile, askForPassword } = useWallet();
- const [error, setError] = useState(null);
- const { createHDWallet } = useHDWallet();
-
- useEffect(() => {
- setAsideTitle('Add Key Source');
- }, []);
-
- async function createWebAuthn() {
- if (!profile) {
- throw new Error('No profile found');
- }
- if (keySources.find((keySource) => keySource.source === 'web-authn')) {
- // basically its possible to have multiple web-authn sources
- // but for now just for simplicity we will only allow one
- alert('WebAuthn already created');
- throw new Error('WebAuthn already created');
- }
- const service = (await keySourceManager.get(
- 'web-authn',
- )) as WebAuthnService;
-
- await service.register(profile.uuid);
- }
-
- const registerHDWallet =
- (type: 'HD-BIP44' | 'HD-chainweaver') => async () => {
- const password = await askForPassword();
- if (!password || !profile) {
- return;
- }
- await createHDWallet(profile?.uuid, type, password);
- };
-
- return (
- <>
- {error && (
-
-
- {error}
-
-
- )}
-
- handleSetAsideExpanded(false)}
- onSave={async (sourcesToInstall) => {
- try {
- await Promise.all(
- sourcesToInstall.map(async (source) => {
- switch (source) {
- case 'HD-BIP44':
- await registerHDWallet('HD-BIP44')();
- break;
- case 'HD-chainweaver':
- await registerHDWallet('HD-chainweaver')();
- break;
- case 'web-authn':
- await createWebAuthn();
- break;
- default:
- throw new Error('Unsupported key source');
- }
- }),
- );
- } catch (error: any) {
- setError(error?.message ?? JSON.stringify(error));
- } finally {
- handleSetAsideExpanded(false);
- }
- keySourceManager.disconnect();
- }}
- installed={keySources.map((k) => k.source)}
- />
- >
- );
-};
-
-export default KeySource;
diff --git a/packages/apps/dev-wallet/src/Components/Aside/views/NewAsset.tsx b/packages/apps/dev-wallet/src/Components/Aside/views/NewAsset.tsx
deleted file mode 100644
index ad030e08f9..0000000000
--- a/packages/apps/dev-wallet/src/Components/Aside/views/NewAsset.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { AddToken } from '@/Components/Assets/AddToken';
-import { useLayout } from '@kadena/kode-ui/patterns';
-import { useEffect } from 'react';
-
-const NewAsset = () => {
- const { setAsideTitle } = useLayout();
-
- useEffect(() => {
- setAsideTitle('Add new Asset');
- }, []);
-
- return ;
-};
-
-export default NewAsset;
diff --git a/packages/apps/dev-wallet/src/Components/Assets/AddToken.tsx b/packages/apps/dev-wallet/src/Components/Assets/AddTokenForm.tsx
similarity index 61%
rename from packages/apps/dev-wallet/src/Components/Assets/AddToken.tsx
rename to packages/apps/dev-wallet/src/Components/Assets/AddTokenForm.tsx
index 943f8868e3..48d6561cab 100644
--- a/packages/apps/dev-wallet/src/Components/Assets/AddToken.tsx
+++ b/packages/apps/dev-wallet/src/Components/Assets/AddTokenForm.tsx
@@ -3,7 +3,13 @@ import { useWallet } from '@/modules/wallet/wallet.hook';
import { queryAllChainsClient } from '@kadena/client-utils/core';
import { composePactCommand, execution } from '@kadena/client/fp';
import { Button, Notification, Stack, TextField } from '@kadena/kode-ui';
-import { useLayout } from '@kadena/kode-ui/patterns';
+import {
+ RightAside,
+ RightAsideContent,
+ RightAsideFooter,
+ RightAsideHeader,
+ useLayout,
+} from '@kadena/kode-ui/patterns';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
@@ -12,7 +18,7 @@ interface TokenForm {
symbol: string;
}
-export function AddToken() {
+export function AddTokenForm({ isOpen }: { isOpen: boolean }) {
const { register, handleSubmit } = useForm({
defaultValues: {
contract: '',
@@ -21,7 +27,7 @@ export function AddToken() {
});
const { activeNetwork } = useWallet();
- const { handleSetAsideExpanded } = useLayout();
+ const { setIsRightAsideExpanded } = useLayout();
const [error, setError] = useState(null);
async function onSubmit(data: TokenForm) {
@@ -57,25 +63,42 @@ export function AddToken() {
} as const;
await accountRepository.addFungible(token);
- handleSetAsideExpanded(false);
+ setIsRightAsideExpanded(false);
} catch (e: any) {
setError(e?.message || e);
}
}
return (
-
+
+
+
);
}
diff --git a/packages/apps/dev-wallet/src/Components/Assets/Assets.tsx b/packages/apps/dev-wallet/src/Components/Assets/Assets.tsx
index 7f5dbf7e95..76b751766b 100644
--- a/packages/apps/dev-wallet/src/Components/Assets/Assets.tsx
+++ b/packages/apps/dev-wallet/src/Components/Assets/Assets.tsx
@@ -1,11 +1,11 @@
import { Fungible, IAccount } from '@/modules/account/account.repository';
-import { createAsideUrl } from '@/utils/createAsideUrl';
import { MonoWallet } from '@kadena/kode-icons/system';
-import { Heading, Link as LinkUI, Stack, Text } from '@kadena/kode-ui';
+import { Button, Heading, Stack, Text } from '@kadena/kode-ui';
+import { useLayout } from '@kadena/kode-ui/patterns';
import { PactNumber } from '@kadena/pactjs';
import classNames from 'classnames';
import { useMemo } from 'react';
-import { Link } from 'react-router-dom';
+import { AddTokenForm } from './AddTokenForm';
import { assetBoxClass } from './style.css';
export function Assets({
@@ -21,6 +21,7 @@ export function Assets({
fungibles: Fungible[];
showAddToken?: boolean;
}) {
+ const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout();
const assets = useMemo(() => {
return fungibles.map((item) => {
const acs = accounts.filter((a) => a.contract === item.contract);
@@ -35,47 +36,51 @@ export function Assets({
}, [accounts, fungibles]);
return (
-
-
- Your Assets
- {showAddToken && (
-
- Add new asset
-
- )}
-
-
- {assets.map((asset) => (
- setSelectedContract(asset.contract)}
- >
-
-
-
+ <>
+
+
+
+ Your Assets
+ {showAddToken && (
+
+ )}
+
+
+ {assets.map((asset) => (
+ setSelectedContract(asset.contract)}
+ >
+
+
+
+
+ {asset.symbol}
+
+
+ {asset.balance}
- {asset.symbol}
-
- {asset.balance}
-
-
- ))}
+ ))}
+
-
+ >
);
}
diff --git a/packages/apps/dev-wallet/src/Components/KeysetDialog/KeySetDialog.tsx b/packages/apps/dev-wallet/src/Components/KeysetDialog/KeySetDialog.tsx
index 066a55fff4..1e882e2092 100644
--- a/packages/apps/dev-wallet/src/Components/KeysetDialog/KeySetDialog.tsx
+++ b/packages/apps/dev-wallet/src/Components/KeysetDialog/KeySetDialog.tsx
@@ -108,7 +108,7 @@ export function KeySetDialog({
{addedKeys.length === 0 && No keys added yet!}
{addedKeys.map((key) => (
-
+
void;
onDone: (contect: IContact) => void;
+ isOpen: boolean;
}) {
const prompt = usePrompt();
const { activeNetwork } = useWallet();
@@ -36,8 +43,8 @@ export function ContactForm({
control,
getValues,
handleSubmit,
- reset,
formState: { isValid },
+ reset,
} = useForm({
defaultValues: input ?? {
name: '',
@@ -54,7 +61,7 @@ export function ContactForm({
discoverdAccount: undefined,
},
);
- }, [input]);
+ }, [input?.uuid]);
const createContact = useCallback(
async ({ discoverdAccount, ...data }: IContactFormData) => {
@@ -98,58 +105,56 @@ export function ContactForm({
if (!activeNetwork) return null;
return (
- <>
-
- >
+
);
}
diff --git a/packages/apps/dev-wallet/src/pages/contacts/contacts.tsx b/packages/apps/dev-wallet/src/pages/contacts/contacts.tsx
index ffd259e093..a808948568 100644
--- a/packages/apps/dev-wallet/src/pages/contacts/contacts.tsx
+++ b/packages/apps/dev-wallet/src/pages/contacts/contacts.tsx
@@ -1,9 +1,11 @@
import { ConfirmDeletion } from '@/Components/ConfirmDeletion/ConfirmDeletion';
import { ListItem } from '@/Components/ListItem/ListItem';
import { usePrompt } from '@/Components/PromptProvider/Prompt';
-import { contactRepository } from '@/modules/contact/contact.repository';
+import {
+ contactRepository,
+ IContact,
+} from '@/modules/contact/contact.repository';
import { useWallet } from '@/modules/wallet/wallet.hook';
-import { createAsideUrl } from '@/utils/createAsideUrl';
import { shorten } from '@/utils/helpers';
import {
MonoAccountBalanceWallet,
@@ -15,17 +17,23 @@ import {
ContextMenu,
ContextMenuItem,
Heading,
- Link as LinkUI,
Stack,
Text,
} from '@kadena/kode-ui';
import { useLayout } from '@kadena/kode-ui/patterns';
-import { Link, useNavigate } from 'react-router-dom';
+import { useState } from 'react';
import { panelClass } from '../home/style.css';
+import { ContactForm } from './Components/ContactForm';
export function Contacts() {
- useLayout({
- appContext: undefined,
+ const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout({
+ appContext: {
+ visual: ,
+ label: 'Add Contact',
+ onPress: () => {
+ setIsRightAsideExpanded(true);
+ },
+ },
breadCrumbs: [
{
label: 'Contacts',
@@ -34,87 +42,100 @@ export function Contacts() {
},
],
});
- const navigate = useNavigate();
+ const [editContact, setEditContact] = useState();
const { contacts } = useWallet();
const prompt = usePrompt();
+ const closeForm = () => {
+ setIsRightAsideExpanded(false);
+ setEditContact(undefined);
+ };
+
return (
-
-
- Contacts
+ <>
+
-
- Add Contact
-
-
-
- {contacts.map((contact) => (
-
-
-
- {contact.name}
- {contact.email && ({contact.email})}
-
-
+
+
+ Contacts
+
+
+
+
+ {contacts.map((contact) => (
+
+
- {' '}
- {shorten(contact.account.address)}
+ {contact.name}
+ {contact.email && ({contact.email})}
+
+
+ {' '}
+ {shorten(contact.account.address)}
+
- }
- variant="transparent"
- isCompact
+ }
+ variant="transparent"
+ isCompact
+ />
+ }
+ >
+ {
+ setIsRightAsideExpanded(true);
+ setEditContact(contact);
+ }}
/>
- }
- >
- {
- navigate(
- createAsideUrl('AddContact', {
- contactId: contact.uuid,
- }),
- );
- }}
- />
- {
- const confirm = await prompt((resolve, reject) => (
- reject()}
- onDelete={() => resolve(true)}
- title="Delete Contact"
- description="Are you sure you want to delete this contact?"
- />
- ));
- if (confirm) {
- await contactRepository.deleteContact(contact.uuid);
- }
- }}
- />
-
+ {
+ const confirm = await prompt((resolve, reject) => (
+ reject()}
+ onDelete={() => resolve(true)}
+ title="Delete Contact"
+ description="Are you sure you want to delete this contact?"
+ />
+ ));
+ if (confirm) {
+ await contactRepository.deleteContact(contact.uuid);
+ }
+ }}
+ />
+
+
-
-
- ))}
+
+ ))}
+
-
+ >
);
}
diff --git a/packages/apps/dev-wallet/src/pages/create-account/create-account.tsx b/packages/apps/dev-wallet/src/pages/create-account/create-account.tsx
index a917685dfd..587c5616a6 100644
--- a/packages/apps/dev-wallet/src/pages/create-account/create-account.tsx
+++ b/packages/apps/dev-wallet/src/pages/create-account/create-account.tsx
@@ -24,25 +24,28 @@ import {
Text,
TextField,
} from '@kadena/kode-ui';
+import { useLayout } from '@kadena/kode-ui/patterns';
import classNames from 'classnames';
import { useState } from 'react';
import { Navigate, useSearchParams } from 'react-router-dom';
import { panelClass } from '../home/style.css.ts';
-import { CreateKeySetDialog } from '../keys/Components/CreateKeySetDialog.tsx';
+import { CreateKeySetForm } from '../keys/Components/CreateKeySetForm.tsx';
import { buttonListClass } from './style.css.ts';
+type IKeySetType =
+ | {
+ item: IKeySet;
+ type: 'keyset';
+ }
+ | {
+ item: IKeyItem;
+ type: 'key';
+ };
+
type AccountType = 'k:account' | 'w:account' | 'r:account';
export function CreateAccount() {
- const [selectedItem, setSelectedItem] = useState<
- | {
- item: IKeySet;
- type: 'keyset';
- }
- | {
- item: IKeyItem;
- type: 'key';
- }
- >();
+ const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout();
+ const [selectedItem, setSelectedItem] = useState();
const [created, setCreated] = useState(null);
const [accountType, setAccountType] = useState('k:account');
const [searchParams] = useSearchParams();
@@ -72,8 +75,6 @@ export function CreateAccount() {
const usedKeysets = filteredAccounts.map((account) => account.keyset?.uuid);
- const [showCreateKeyset, setShowCreateKeyset] = useState(false);
-
const createAccountByKeyset = async (keyset: IKeySet) => {
if (!profile || !activeNetwork || !contract) {
throw new Error('Profile or active network not found');
@@ -154,271 +155,282 @@ export function CreateAccount() {
);
return (
-
-
- Create Account
-
-
- setAlias(e.target.value)} />
+ <>
+ setIsRightAsideExpanded(false)}
+ onDone={(keyset: IKeySet) => {
+ setSelectedItem({
+ item: keyset,
+ type: 'keyset',
+ });
+ }}
+ />
- Choose the account type
- {
- setSelectedItem(undefined);
- setAccountType(type as AccountType);
- }}
- >
-
+
+ Create Account
+
+
+ setAlias(e.target.value)}
+ />
+
+ Choose the account type
+ {
+ setSelectedItem(undefined);
+ setAccountType(type as AccountType);
+ }}
+ >
+
+
+ k: account
- This account will be guarded by a keyset reference. this is
- more suitable if you want to change the guard later without
- creating a new account. Creating this type of account
- requires namespace generation so its not supported yet with
- most of the wallets
+ This account will be guarded by a single key, this is the
+ most relevant way if you are creating a personal account;
+ Also this type of account supposed widely by kadena
+ ecosystem.
+
+
+ Tip: The account guard is immutable and can't be changed.
+
+
+
+ w: account
- Tip: Since the guard can be changed, this type of account is
- more flexible.
+ This account will be guarded by a keyset or (single key when
+ key type is web-authn). This will offers a way to create
+ shared account or more secure account guarded by several
+ keys.
+
+
+ Tip: The account guard is immutable and can't be changed.
-
-
-
-
- {contract && (
-
- {accountType === 'w:account' && (
-
- {showCreateKeyset && (
- setShowCreateKeyset(false)}
- onDone={(keyset) => {
- setSelectedItem({
- item: keyset,
- type: 'keyset',
- });
- }}
- />
- )}
- Keysets
+
+
+
+ r: account (not supposed yet)
+
-
- Create or use a keyset
- }
- onPress={() => setShowCreateKeyset(true)}
- variant="outlined"
- >
- Create a new keyset
-
-
-
- {filteredKeysets.length === 0
- ? 'There is not keyset available to select, create a new one'
- : 'Select on of the following keysets to create account'}
+
+ This account will be guarded by a keyset reference. this
+ is more suitable if you want to change the guard later
+ without creating a new account. Creating this type of
+ account requires namespace generation so its not supported
+ yet with most of the wallets
-
-
- {filteredKeysets.map((keyset) => {
- return (
-
- setSelectedItem({
- item: keyset,
- type: 'keyset',
- })
- }
- >
-
+ Tip: Since the guard can be changed, this type of account
+ is more flexible.
+
+
+
+
+
+
+ {contract && (
+
+ {accountType === 'w:account' && (
+
+ Keysets
+
+
+ Create or use a keyset
+ }
+ onPress={() => setIsRightAsideExpanded(true)}
+ variant="outlined"
+ >
+ Create a new keyset
+
+
+
+ {filteredKeysets.length === 0
+ ? 'There is not keyset available to select, create a new one'
+ : 'Select on of the following keysets to create account'}
+
+
+
+ {filteredKeysets.map((keyset) => {
+ return (
+
+ setSelectedItem({
+ item: keyset,
+ type: 'keyset',
+ })
+ }
>
-
- {}
+
+
+ {}
+
-
-
- );
- })}
+
+ );
+ })}
+
-
- )}
- {['k:account', 'w:account'].includes(accountType) &&
- filteredKeySources.length && (
-
- Keys
-
- {filteredKeySources.map((keySource) => {
- const filteredKeys = keySource.keys.filter(
- (key) => !usedKeys.includes(key.publicKey),
- );
- return (
-
+ )}
+ {['k:account', 'w:account'].includes(accountType) &&
+ filteredKeySources.length && (
+
+ Keys
+
+ {filteredKeySources.map((keySource) => {
+ const filteredKeys = keySource.keys.filter(
+ (key) => !usedKeys.includes(key.publicKey),
+ );
+ return (
- {keySource.source}
-
-
-
- {filteredKeys.length === 0
- ? 'There is not key available to select, create a new one'
- : 'Select on of the following keys to create account'}
-
-
-
- {keySource.keys
- .filter(
- (key) => !usedKeys.includes(key.publicKey),
- )
- .map((key) => {
- return (
-
- setSelectedItem({
- item: key,
- type: 'key',
- })
- }
- >
-
-
-
+
+ {keySource.source}
+
+
+
+
+ {filteredKeys.length === 0
+ ? 'There is not key available to select, create a new one'
+ : 'Select on of the following keys to create account'}
+
+
+
+ {keySource.keys
+ .filter(
+ (key) => !usedKeys.includes(key.publicKey),
+ )
+ .map((key) => {
+ return (
+
+ setSelectedItem({
+ item: key,
+ type: 'key',
+ })
+ }
+ >
+
+
+
+
-
-
- );
- })}
+
+ );
+ })}
+
-
- );
- })}
+ );
+ })}
+
-
- )}
-
- )}
-
-
-
-
+ )}
+
+ )}
+
+
+
+
+
-
-
+
+ >
);
}
diff --git a/packages/apps/dev-wallet/src/pages/home/home-page.tsx b/packages/apps/dev-wallet/src/pages/home/home-page.tsx
index d6d0c77738..20e4302ef2 100644
--- a/packages/apps/dev-wallet/src/pages/home/home-page.tsx
+++ b/packages/apps/dev-wallet/src/pages/home/home-page.tsx
@@ -4,6 +4,7 @@ import { useWallet } from '@/modules/wallet/wallet.hook';
import { panelClass } from '@/pages/home/style.css.ts';
import { useAsync } from '@/utils/useAsync';
import { IPactCommand } from '@kadena/client';
+import { MonoWallet } from '@kadena/kode-icons/system';
import { Box, Heading, Stack, TabItem, Tabs, Text } from '@kadena/kode-ui';
import { useLayout } from '@kadena/kode-ui/patterns';
import { Link } from 'react-router-dom';
@@ -12,13 +13,18 @@ import { TransactionList } from '../transactions/transactions';
export function HomePage() {
const { profile, activeNetwork } = useWallet();
+ const { setIsRightAsideExpanded } = useLayout();
useLayout({
breadCrumbs: [],
- appContext: undefined,
+ appContext: {
+ visual: ,
+ label: 'Add Asset',
+ onPress: () => {
+ setIsRightAsideExpanded(true);
+ },
+ },
});
- console.log('activeNetwork', activeNetwork);
-
const [transactions] = useAsync(
async (profile, activeNetwork) => {
if (profile?.uuid && activeNetwork?.uuid) {
diff --git a/packages/apps/dev-wallet/src/pages/keys/Components/AddKeySourceForm.tsx b/packages/apps/dev-wallet/src/pages/keys/Components/AddKeySourceForm.tsx
index ffa9ae02de..2c6ef0e352 100644
--- a/packages/apps/dev-wallet/src/pages/keys/Components/AddKeySourceForm.tsx
+++ b/packages/apps/dev-wallet/src/pages/keys/Components/AddKeySourceForm.tsx
@@ -1,18 +1,27 @@
import { KeySourceType } from '@/modules/wallet/wallet.repository';
import { Button, Checkbox, Divider, Stack, Text } from '@kadena/kode-ui';
+import {
+ RightAside,
+ RightAsideContent,
+ RightAsideFooter,
+ RightAsideHeader,
+} from '@kadena/kode-ui/patterns';
import { useState } from 'react';
export function AddKeySourceForm({
- onClose,
+ close,
onSave,
installed,
+ isOpen,
}: {
installed: KeySourceType[];
- onClose: () => void;
+ close: () => void;
onSave: (sourcesToInstall: KeySourceType[]) => void;
+ isOpen: boolean;
}) {
const [localInstalled, setLocalInstalled] =
useState(installed);
+
const onChange = (source: KeySourceType) => (isSelected: boolean) => {
if (isSelected) {
setLocalInstalled([...localInstalled, source]);
@@ -25,46 +34,44 @@ export function AddKeySourceForm({
onChange: onChange(source),
isSelected: localInstalled.includes(source),
});
+
return (
- <>
-
-
- BIP44 algorithm
-
- This is the default and recommended algorithm for generating keys.
-
-
-
-
-
- Legacy algorithm (chainweaver 1)
-
-
- This is a legacy algorithm used in chainweaver 1, it's not
- recommended to use it for new wallets, use this only if you have a
- wallet created in chainweaver 1
-
+
+
+
+
+
+ BIP44 algorithm
+
+ This is the default and recommended algorithm for generating keys.
+
+
+
+
+
+ Legacy algorithm (chainweaver 1)
+
+
+ This is a legacy algorithm used in chainweaver 1, it's not
+ recommended to use it for new wallets, use this only if you have a
+ wallet created in chainweaver 1
+
+
+
+
+
+ WebAuthn External keys (Experimental)
+
+
+ This is an experimental feature that allows you to use your
+ compatible devices to generate keys, The keys are stored in the
+ device and cant be recovered with the wallet if lost the device
+
+
-
-
-
- WebAuthn External keys (Experimental)
-
-
- This is an experimental feature that allows you to use your
- compatible devices to generate keys, The keys are stored in the
- device and cant be recovered with the wallet if lost the device
-
-
-
-
-
-
- >
+
+
);
}
diff --git a/packages/apps/dev-wallet/src/pages/keys/Components/CreateKeySetDialog.tsx b/packages/apps/dev-wallet/src/pages/keys/Components/CreateKeySetForm.tsx
similarity index 93%
rename from packages/apps/dev-wallet/src/pages/keys/Components/CreateKeySetDialog.tsx
rename to packages/apps/dev-wallet/src/pages/keys/Components/CreateKeySetForm.tsx
index 7ab154bed6..4569c97120 100644
--- a/packages/apps/dev-wallet/src/pages/keys/Components/CreateKeySetDialog.tsx
+++ b/packages/apps/dev-wallet/src/pages/keys/Components/CreateKeySetForm.tsx
@@ -1,5 +1,4 @@
import { Key } from '@/Components/Key/Key';
-import { displayContentsClass } from '@/Components/Sidebar/style.css';
import {
accountRepository,
IKeySet,
@@ -14,10 +13,6 @@ import {
Button,
Combobox,
ComboboxItem,
- Dialog,
- DialogContent,
- DialogFooter,
- DialogHeader,
Heading,
Notification,
Select,
@@ -26,6 +21,12 @@ import {
Text,
TextField,
} from '@kadena/kode-ui';
+import {
+ RightAside,
+ RightAsideContent,
+ RightAsideFooter,
+ RightAsideHeader,
+} from '@kadena/kode-ui/patterns';
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { keyColumnClass, keyItemClass } from './style.css';
@@ -38,14 +39,14 @@ interface IKeysetForm {
alias: string;
}
-export function CreateKeySetDialog({
- isOpen,
+export function CreateKeySetForm({
close,
onDone,
+ isOpen,
}: {
- isOpen: boolean;
close: () => void;
onDone?: (keyset: IKeySet) => void;
+ isOpen: boolean;
}) {
const { register, control, getValues, setValue, handleSubmit } =
useForm({
@@ -59,6 +60,7 @@ export function CreateKeySetDialog({
});
const [error, setError] = useState(null);
const { keySources, createKey, profile, keysets, contacts } = useWallet();
+
const flattenKeys = keySources
.map((keySource) => keySource.keys.map((key) => ({ key, keySource })))
.flat();
@@ -120,22 +122,11 @@ export function CreateKeySetDialog({
}
return (
-
+
);
}
diff --git a/packages/apps/dev-wallet/src/pages/keys/Components/KeySets.tsx b/packages/apps/dev-wallet/src/pages/keys/Components/KeySets.tsx
index b5df595951..15fb42863d 100644
--- a/packages/apps/dev-wallet/src/pages/keys/Components/KeySets.tsx
+++ b/packages/apps/dev-wallet/src/pages/keys/Components/KeySets.tsx
@@ -3,55 +3,55 @@ import { useWallet } from '@/modules/wallet/wallet.hook';
import { shorten } from '@/utils/helpers';
import { MonoKey } from '@kadena/kode-icons/system';
import { Button, Heading, Stack, Text } from '@kadena/kode-ui';
-import { useState } from 'react';
-import { CreateKeySetDialog } from './CreateKeySetDialog';
+import { useLayout } from '@kadena/kode-ui/patterns';
+import { CreateKeySetForm } from './CreateKeySetForm';
export function KeySets() {
+ const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout();
const { keysets } = useWallet();
- const [showCreateKeyset, setShowCreateKeyset] = useState(false);
return (
-
- {showCreateKeyset && (
- setShowCreateKeyset(false)}
- />
- )}
-
- Key Sets
- setShowCreateKeyset(true)}
- variant="outlined"
- isCompact
- >
- Create Key Set
-
-
+ <>
+ setIsRightAsideExpanded(false)}
+ />
- {keysets
- .filter(({ guard }) => guard.keys.length >= 2)
- .map((keySet) => (
-
-
-
- {keySet.alias}
- {keySet.principal}
-
-
-
- {keySet.guard.pred}:
- {keySet.guard.keys.map((key) => (
-
-
-
-
- {shorten(key)}{' '}
+
+ Key Sets
+ setIsRightAsideExpanded(true)}
+ variant="outlined"
+ isCompact
+ >
+ Create Key Set
+
+
+
+ {keysets
+ .filter(({ guard }) => guard.keys.length >= 2)
+ .map((keySet) => (
+
+
+
+ {keySet.alias}
+ {keySet.principal}
- ))}
-
-
- ))}
+
+
+ {keySet.guard.pred}:
+ {keySet.guard.keys.map((key) => (
+
+
+
+
+ {shorten(key)}{' '}
+
+ ))}
+
+
+ ))}
+
-
+ >
);
}
diff --git a/packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx b/packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx
index eea2e60853..1adcef170f 100644
--- a/packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx
+++ b/packages/apps/dev-wallet/src/pages/keys/Components/Keys.tsx
@@ -1,6 +1,8 @@
import { ListItem } from '@/Components/ListItem/ListItem.tsx';
+import { useHDWallet } from '@/modules/key-source/hd-wallet/hd-wallet.tsx';
+import { keySourceManager } from '@/modules/key-source/key-source-manager';
+import { WebAuthnService } from '@/modules/key-source/web-authn/webauthn';
import { useWallet } from '@/modules/wallet/wallet.hook';
-import { createAsideUrl } from '@/utils/createAsideUrl.ts';
import { shorten } from '@/utils/helpers.ts';
import { MonoAdd, MonoMoreVert } from '@kadena/kode-icons/system';
import {
@@ -9,32 +11,93 @@ import {
ContextMenuDivider,
ContextMenuItem,
Heading,
- Link as LinkUI,
Stack,
Text,
} from '@kadena/kode-ui';
-import { Link } from 'react-router-dom';
+import { useLayout } from '@kadena/kode-ui/patterns';
+import { useState } from 'react';
import { panelClass } from '../../home/style.css.ts';
+import { AddKeySourceForm } from './AddKeySourceForm.tsx';
export function Keys() {
- const { keySources, createKey } = useWallet();
+ const { keySources, profile, askForPassword, createKey } = useWallet();
+ const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout();
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ const [_, setError] = useState(null);
+ const { createHDWallet } = useHDWallet();
+ async function createWebAuthn() {
+ if (!profile) {
+ throw new Error('No profile found');
+ }
+ if (keySources.find((keySource) => keySource.source === 'web-authn')) {
+ // basically its possible to have multiple web-authn sources
+ // but for now just for simplicity we will only allow one
+ alert('WebAuthn already created');
+ throw new Error('WebAuthn already created');
+ }
+ const service = (await keySourceManager.get(
+ 'web-authn',
+ )) as WebAuthnService;
+
+ await service.register(profile.uuid);
+ }
+
+ const registerHDWallet =
+ (type: 'HD-BIP44' | 'HD-chainweaver') => async () => {
+ const password = await askForPassword();
+ if (!password || !profile) {
+ return;
+ }
+ await createHDWallet(profile?.uuid, type, password);
+ };
return (
<>
+ setIsRightAsideExpanded(false)}
+ onSave={async (sourcesToInstall) => {
+ setIsRightAsideExpanded(false);
+ try {
+ await Promise.all(
+ sourcesToInstall.map(async (source) => {
+ switch (source) {
+ case 'HD-BIP44':
+ await registerHDWallet('HD-BIP44')();
+ break;
+ case 'HD-chainweaver':
+ await registerHDWallet('HD-chainweaver')();
+ break;
+ case 'web-authn':
+ await createWebAuthn();
+ break;
+ default:
+ throw new Error('Unsupported key source');
+ }
+ }),
+ );
+ } catch (error: any) {
+ setError(error?.message ?? JSON.stringify(error));
+ }
+ keySourceManager.disconnect();
+ }}
+ installed={keySources.map((k) => k.source)}
+ />
Your Keys
- {
+ setIsRightAsideExpanded(true);
+ }}
>
Add key Source
-
+
@@ -83,7 +146,7 @@ export function Keys() {
{keySource.keys.map((key) => (
-
+
& {
+ uuid?: undefined;
+ })
+ | INetwork;
+
+interface INewNetwork {
+ uuid: UUID | undefined;
+ networkId: string;
+ name: string;
+ hosts: {
+ url: string;
+ submit: boolean;
+ read: boolean;
+ confirm: boolean;
+ isHealthy?: boolean;
+ nodeVersion?: string;
+ }[];
+}
+
+export const getNewNetwork = (): INetworkWithOptionalUuid => ({
+ uuid: undefined,
+ networkId: '',
+ name: '',
+ hosts: [
+ {
+ url: '',
+ submit: false,
+ read: false,
+ confirm: false,
+ },
+ ],
+});
+
+export function NetworkForm({
+ network,
+ onClose,
+ onSave: onDone,
+ isOpen,
+}: {
+ network: INetworkWithOptionalUuid;
+ onSave: (network: INetworkWithOptionalUuid) => void;
+ onClose: () => void;
+ isOpen: boolean;
+}) {
+ const {
+ control,
+ register,
+ handleSubmit,
+ getValues,
+ setValue,
+ watch,
+ formState,
+ reset,
+ } = useForm({
+ defaultValues: network,
+ mode: 'all',
+ });
+ const { fields, append, remove } = useFieldArray({ control, name: 'hosts' });
+ async function create(updNetwork: INewNetwork) {
+ const hosts = updNetwork.hosts.map(
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ ({ isHealthy, nodeVersion, ...host }) => host,
+ );
+ onDone({
+ ...updNetwork,
+ hosts,
+ });
+ }
+
+ useEffect(() => {
+ reset(network ?? getNewNetwork());
+ }, [network.uuid]);
+
+ const hosts = watch('hosts');
+ const networkId = watch('networkId');
+
+ const isNetworkIdValid =
+ hosts.length > 0 &&
+ networkId.length > 0 &&
+ hosts.every((host) => host.nodeVersion === networkId);
+
+ useEffect(() => {
+ if (networkId) {
+ const hosts = getValues('hosts');
+ hosts.forEach(({ url }, index) =>
+ fetchNetworkId(url).then((nodeVersion) => {
+ setValue(`hosts.${index}.nodeVersion`, nodeVersion);
+ setValue(`hosts.${index}.isHealthy`, nodeVersion !== undefined);
+ }),
+ );
+ }
+ }, [networkId, getValues, setValue]);
+
+ return (
+
+
+
+
+
+
+
+
+ Host Urls
+
+ append({
+ url: '',
+ submit: true,
+ read: true,
+ confirm: true,
+ isHealthy: undefined,
+ nodeVersion: undefined,
+ })
+ }
+ >
+ + host
+
+
+
+ {fields.map((field, index) => {
+ const nodeVersion = watch(`hosts.${index}.nodeVersion`);
+ const isHealthy = watch(`hosts.${index}.isHealthy`);
+ return (
+
+
+
+ {
+ const host = getValues(`hosts.${index}.url`);
+ if (!host) {
+ return;
+ }
+ fetchNetworkId(host).then((nodeVersion) => {
+ setValue(
+ `hosts.${index}.nodeVersion`,
+ nodeVersion,
+ );
+ setValue(
+ `hosts.${index}.isHealthy`,
+ nodeVersion !== undefined,
+ );
+ });
+ },
+ })}
+ />
+
+ remove(index)}
+ variant="transparent"
+ >
+
+
+
+ {nodeVersion && nodeVersion !== networkId ? (
+
+
+
+ the host networkId is
+ {nodeVersion}
+ {' '}
+ but networkId field is {networkId}
+
+
+ ) : null}
+
+ );
+ })}
+
+
+
+
+ onClose()} type="reset">
+ Cancel
+
+
+ Save
+
+
+
+
+ );
+}
diff --git a/packages/apps/dev-wallet/src/pages/networks/Components/network-form.tsx b/packages/apps/dev-wallet/src/pages/networks/Components/network-form.tsx
deleted file mode 100644
index 071a943998..0000000000
--- a/packages/apps/dev-wallet/src/pages/networks/Components/network-form.tsx
+++ /dev/null
@@ -1,192 +0,0 @@
-import { displayContentsClass } from '@/Components/Sidebar/style.css';
-import { INetwork } from '@/modules/network/network.repository';
-import { fetchNetworkId } from '@/modules/network/network.service';
-import { UUID } from '@/modules/types';
-import { Label } from '@/pages/transaction/components/helpers';
-import {
- failureClass,
- pendingClass,
- successClass,
-} from '@/pages/transaction/components/style.css';
-import { MonoCircle, MonoDelete, MonoWarning } from '@kadena/kode-icons/system';
-import { Button, Heading, Stack, Text, TextField } from '@kadena/kode-ui';
-import classNames from 'classnames';
-import { useEffect } from 'react';
-import { useFieldArray, useForm } from 'react-hook-form';
-
-export type INetworkWithOptionalUuid =
- | (Omit & {
- uuid?: undefined;
- })
- | INetwork;
-
-interface INewNetwork {
- uuid: UUID | undefined;
- networkId: string;
- name: string;
- hosts: {
- url: string;
- submit: boolean;
- read: boolean;
- confirm: boolean;
- isHealthy?: boolean;
- nodeVersion?: string;
- }[];
-}
-
-export function NetworkForm({
- network,
- onSave: onDone,
-}: {
- network: INetworkWithOptionalUuid;
- onSave: (network: INetworkWithOptionalUuid) => void;
-}) {
- const {
- control,
- register,
- handleSubmit,
- getValues,
- setValue,
- watch,
- formState,
- } = useForm({
- defaultValues: network,
- mode: 'all',
- });
- const { fields, append, remove } = useFieldArray({ control, name: 'hosts' });
- async function create(updNetwork: INewNetwork) {
- const hosts = updNetwork.hosts.map(
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- ({ isHealthy, nodeVersion, ...host }) => host,
- );
- onDone({
- ...updNetwork,
- hosts,
- });
- }
-
- const hosts = watch('hosts');
- const networkId = watch('networkId');
-
- const isNetworkIdValid =
- hosts.length > 0 &&
- networkId.length > 0 &&
- hosts.every((host) => host.nodeVersion === networkId);
-
- useEffect(() => {
- if (networkId) {
- const hosts = getValues('hosts');
- hosts.forEach(({ url }, index) =>
- fetchNetworkId(url).then((nodeVersion) => {
- setValue(`hosts.${index}.nodeVersion`, nodeVersion);
- setValue(`hosts.${index}.isHealthy`, nodeVersion !== undefined);
- }),
- );
- }
- }, [networkId, getValues, setValue]);
-
- return (
- <>
-
-
-
-
-
- Host Urls
-
- append({
- url: '',
- submit: true,
- read: true,
- confirm: true,
- isHealthy: undefined,
- nodeVersion: undefined,
- })
- }
- >
- + host
-
-
-
- {fields.map((field, index) => {
- const nodeVersion = watch(`hosts.${index}.nodeVersion`);
- const isHealthy = watch(`hosts.${index}.isHealthy`);
- return (
-
-
-
- {
- const host = getValues(`hosts.${index}.url`);
- if (!host) {
- return;
- }
- fetchNetworkId(host).then((nodeVersion) => {
- setValue(`hosts.${index}.nodeVersion`, nodeVersion);
- setValue(
- `hosts.${index}.isHealthy`,
- nodeVersion !== undefined,
- );
- });
- },
- })}
- />
-
- remove(index)}
- variant="transparent"
- >
-
-
-
- {nodeVersion && nodeVersion !== networkId ? (
-
-
-
- the host networkId is {nodeVersion} but
- networkId field is {networkId}
-
-
- ) : null}
-
- );
- })}
-
-
- Save
-
-
-
- >
- );
-}
diff --git a/packages/apps/dev-wallet/src/pages/networks/networks.tsx b/packages/apps/dev-wallet/src/pages/networks/networks.tsx
index e9a0e938c2..a784050e35 100644
--- a/packages/apps/dev-wallet/src/pages/networks/networks.tsx
+++ b/packages/apps/dev-wallet/src/pages/networks/networks.tsx
@@ -3,41 +3,19 @@ import { networkRepository } from '@/modules/network/network.repository';
import { useWallet } from '@/modules/wallet/wallet.hook';
import { createAsideUrl } from '@/utils/createAsideUrl';
import { MonoWifiTethering, MonoWorkspaces } from '@kadena/kode-icons/system';
-import {
- Button,
- Dialog,
- DialogContent,
- DialogHeader,
- Heading,
- Link,
- Stack,
- Text,
-} from '@kadena/kode-ui';
+import { Button, Heading, Link, Stack, Text } from '@kadena/kode-ui';
import { useLayout } from '@kadena/kode-ui/patterns';
import { useState } from 'react';
import { panelClass } from '../home/style.css';
import {
+ getNewNetwork,
INetworkWithOptionalUuid,
NetworkForm,
-} from './Components/network-form';
-
-const getNewNetwork = (): INetworkWithOptionalUuid => ({
- uuid: undefined,
- networkId: '',
- name: '',
- hosts: [
- {
- url: '',
- submit: false,
- read: false,
- confirm: false,
- },
- ],
-});
+} from './Components/NetworkForm';
export function Networks() {
const { networks } = useWallet();
- const [showNetworkModal, setShowNetworkModal] = useState(false);
+ const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout();
const [selectedNetwork, setSelectedNetwork] =
useState(() => getNewNetwork());
useLayout({
@@ -55,29 +33,25 @@ export function Networks() {
return (
<>
-
+ {
+ setIsRightAsideExpanded(false);
+ }}
+ onSave={async (updNetwork) => {
+ if (updNetwork.uuid) {
+ await networkRepository.updateNetwork(updNetwork);
+ } else {
+ await networkRepository.addNetwork({
+ ...updNetwork,
+ uuid: crypto.randomUUID(),
+ });
+ }
+ setIsRightAsideExpanded(false);
+ }}
+ network={selectedNetwork}
+ />
+
{
setSelectedNetwork(getNewNetwork());
- setShowNetworkModal(true);
+ setTimeout(() => {
+ setIsRightAsideExpanded(true);
+ }, 0);
}}
>
Add Network
@@ -126,7 +102,9 @@ export function Networks() {
variant="outlined"
onPress={() => {
setSelectedNetwork(network);
- setShowNetworkModal(true);
+ setTimeout(() => {
+ setIsRightAsideExpanded(true);
+ }, 0);
}}
>
Edit
diff --git a/packages/apps/dev-wallet/src/pages/transfer-v2/Steps/Result.tsx b/packages/apps/dev-wallet/src/pages/transfer-v2/Steps/Result.tsx
index c219521d4e..3bc423fd88 100644
--- a/packages/apps/dev-wallet/src/pages/transfer-v2/Steps/Result.tsx
+++ b/packages/apps/dev-wallet/src/pages/transfer-v2/Steps/Result.tsx
@@ -92,15 +92,15 @@ export function Result({
Transfers
{Object.entries(groupedTransfers).map(([receiver, tx]) => (
-
-
+
+
Receiver: {shorten(receiver)}
Total Amount: {tx[0].purpose.data.totalAmount}
{tx.map((t) => {
return (
-
+
Tx: {shorten(t.hash)}
Chain: {t.purpose.data.chainId}
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/SideBar.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/SideBar.tsx
index bf0f6cb8ce..dc9dab3abc 100644
--- a/packages/libs/kode-ui/src/patterns/SideBarLayout/SideBar.tsx
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/SideBar.tsx
@@ -53,9 +53,10 @@ export const SideBar: FC = ({
return (
<>
- handleExpand(e as unknown as PressEvent)}
/>
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/aside.css.ts b/packages/libs/kode-ui/src/patterns/SideBarLayout/aside.css.ts
index 4287267760..5c81591378 100644
--- a/packages/libs/kode-ui/src/patterns/SideBarLayout/aside.css.ts
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/aside.css.ts
@@ -111,9 +111,12 @@ export const asideContentClass = style([
atoms({
padding: 'sm',
paddingBlockStart: 'md',
-
flex: 1,
}),
+ {
+ overflowY: 'scroll',
+ height: '100dvh',
+ },
responsiveStyle({
xs: {
backgroundColor: token('color.background.layer.default'),
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/LayoutProvider.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/LayoutProvider.tsx
index 620e336cd5..f91d973185 100644
--- a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/LayoutProvider.tsx
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/LayoutProvider.tsx
@@ -23,12 +23,10 @@ export interface ISideBarBreadCrumb {
visual?: React.ReactElement;
}
export interface ILayoutContext {
- isAsideExpanded: boolean;
isExpanded: boolean;
handleToggleExpand: (e: PressEvent) => void;
handleSetExpanded: (value: boolean) => void;
handleToggleAsideExpand: (e: PressEvent) => void;
- handleSetAsideExpanded: (value: boolean) => void;
appContext?: IAppContextProps;
setAppContext: (context?: IAppContextProps) => void;
breadCrumbs: ISideBarBreadCrumb[];
@@ -36,11 +34,14 @@ export interface ILayoutContext {
setLocation: (location?: ISideBarLayoutLocation | undefined) => void;
location?: ISideBarLayoutLocation;
isActiveUrl: (url?: string) => boolean;
- asideTitle?: string;
- setAsideTitle: (value?: string) => void;
+ rightAsideTitle?: string;
+ setRightAsideTitle: (value?: string) => void;
+ rightAsideRef?: HTMLDivElement | null;
+ setRightAsideRef: (value?: HTMLDivElement | null) => void;
+ isRightAsideExpanded: boolean;
+ setIsRightAsideExpanded: (value: boolean) => void;
}
export const LayoutContext = createContext({
- isAsideExpanded: false,
isExpanded: true,
handleToggleExpand: () => {},
handleSetExpanded: () => {},
@@ -52,12 +53,12 @@ export const LayoutContext = createContext({
breadCrumbs: [],
setLocation: () => {},
isActiveUrl: () => {},
- setAsideTitle: () => {},
+ setRightAsideTitle: () => {},
+ isRightAsideExpanded: false,
+ setIsRightAsideExpanded: () => {},
});
-export interface IuseLayoutProps extends ILayoutContext {
- initPage: (props: Pick) => void;
-}
+export interface IuseLayoutProps extends ILayoutContext {}
export const useLayout = (
props?: Pick,
@@ -93,8 +94,12 @@ export const useLayout = (
export interface ILayoutProvider extends PropsWithChildren {}
export const LayoutProvider: FC = ({ children }) => {
- const [isAsideExpanded, setIsAsideExpanded] = useState(false);
- const [asideTitle, setAsideTitleState] = useState('');
+ const [rightAsideRef, setRightAsideRefState] =
+ useState(null);
+ const [isRightAsideExpanded, setIsRightAsideExpanded] = useState(false);
+ const [rightAsideTitle, setRightAsideTitleState] = useState<
+ string | undefined
+ >('');
const [isExpanded, setIsExpanded] = useState(false);
const [location, setLocationState] = useState<
ISideBarLayoutLocation | undefined
@@ -113,21 +118,21 @@ export const LayoutProvider: FC = ({ children }) => {
const handleToggleAsideExpand = useCallback(
(e: PressEvent) => {
- if (isAsideExpanded) {
+ if (isRightAsideExpanded) {
location?.push(`${location?.url}`);
}
- setIsAsideExpanded((v) => !v);
+ setIsRightAsideExpanded((v) => !v);
},
[location?.url],
);
- const handleSetAsideExpanded = useCallback(
+ const handleSetRightAsideExpanded = useCallback(
(value: boolean) => {
if (!value) {
location?.push(`${location?.url}`);
}
- setIsAsideExpanded(value);
+ setIsRightAsideExpanded(value);
},
[location?.url],
);
@@ -142,8 +147,12 @@ export const LayoutProvider: FC = ({ children }) => {
const setLocation = (value?: ISideBarLayoutLocation | undefined) => {
setLocationState(value);
};
- const setAsideTitle = (value?: string) => {
- setAsideTitleState(value);
+ const setRightAsideTitle = (value?: string) => {
+ setRightAsideTitleState(value);
+ };
+
+ const setRightAsideRef = (value?: HTMLDivElement | null) => {
+ setRightAsideRefState(value ? value : null);
};
const isActiveUrl = (url?: string) => {
@@ -153,12 +162,10 @@ export const LayoutProvider: FC = ({ children }) => {
return (
= ({ children }) => {
setLocation,
location,
isActiveUrl,
- asideTitle,
- setAsideTitle,
+ rightAsideTitle,
+ setRightAsideTitle,
+ rightAsideRef,
+ setRightAsideRef,
+ isRightAsideExpanded,
+ setIsRightAsideExpanded: handleSetRightAsideExpanded,
}}
>
{children}
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAside.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAside.tsx
new file mode 100644
index 0000000000..01f834df32
--- /dev/null
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAside.tsx
@@ -0,0 +1,20 @@
+import type { FC, PropsWithChildren } from 'react';
+import React from 'react';
+import { createPortal } from 'react-dom';
+import { useLayout } from '../LayoutProvider';
+import { rightAsideClass } from './style.css';
+
+export interface iRightAside extends PropsWithChildren {
+ isOpen: boolean;
+}
+
+export const RightAside: FC = ({ children, isOpen }) => {
+ const { rightAsideRef } = useLayout();
+
+ if (!isOpen || !rightAsideRef) return null;
+
+ return createPortal(
+ ,
+ rightAsideRef,
+ );
+};
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideContent.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideContent.tsx
new file mode 100644
index 0000000000..479513aafe
--- /dev/null
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideContent.tsx
@@ -0,0 +1,12 @@
+import type { FC, PropsWithChildren } from 'react';
+import React from 'react';
+import { Stack } from './../../../../components';
+import { rightAsideContentClass } from './style.css';
+
+export const RightAsideContent: FC = ({ children }) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideFooter.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideFooter.tsx
new file mode 100644
index 0000000000..c03c4bad83
--- /dev/null
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideFooter.tsx
@@ -0,0 +1,11 @@
+import type { FC, PropsWithChildren } from 'react';
+import React from 'react';
+import { Stack } from './../../../../components';
+
+export const RightAsideFooter: FC = ({ children }) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideHeader.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideHeader.tsx
new file mode 100644
index 0000000000..8637c05c3b
--- /dev/null
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/RightAsideHeader.tsx
@@ -0,0 +1,17 @@
+import type { FC } from 'react';
+import { useEffect } from 'react';
+import { useLayout } from '../LayoutProvider';
+
+export interface iRightAsideHeader {
+ label?: string;
+}
+
+export const RightAsideHeader: FC = ({ label }) => {
+ const { setRightAsideTitle } = useLayout();
+
+ useEffect(() => {
+ setRightAsideTitle(label);
+ }, [label]);
+
+ return null;
+};
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/index.ts b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/index.ts
new file mode 100644
index 0000000000..d48fdfec4f
--- /dev/null
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/index.ts
@@ -0,0 +1,5 @@
+export { RightAside } from './RightAside';
+export { RightAsideContent } from './RightAsideContent';
+export { RightAsideFooter } from './RightAsideFooter';
+export { RightAsideHeader } from './RightAsideHeader';
+export type { iRightAsideHeader } from './RightAsideHeader';
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/style.css.ts b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/style.css.ts
new file mode 100644
index 0000000000..42d6651064
--- /dev/null
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/RightAside/style.css.ts
@@ -0,0 +1,17 @@
+import { atoms, globalStyle, style } from './../../../../styles';
+
+export const rightAsideClass = style([
+ atoms({ display: 'flex', flexDirection: 'column', flex: 1 }),
+ {},
+]);
+export const rightAsideContentClass = style([
+ atoms({ flex: 1, display: 'flex', flexDirection: 'column', width: '100%' }),
+ {},
+]);
+
+globalStyle(`${rightAsideClass} > form `, {
+ display: 'flex',
+ flexDirection: 'column',
+ flex: 1,
+ width: '100%',
+});
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarAside.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarAside.tsx
index 4abeadfdb1..2100dc0cd4 100644
--- a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarAside.tsx
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarAside.tsx
@@ -1,6 +1,6 @@
import { MonoClose } from '@kadena/kode-icons/system';
-import type { FC, PropsWithChildren } from 'react';
-import React, { useEffect } from 'react';
+import type { FC } from 'react';
+import React, { useEffect, useRef } from 'react';
import {
asideContentClass,
asideHeaderClass,
@@ -14,22 +14,29 @@ import type { PressEvent } from './../../../components';
import { Button, Heading, Stack } from './../../../components';
import { useLayout } from './LayoutProvider';
-export const SideBarAside: FC<
- PropsWithChildren<{
- hasTopBanner?: boolean;
- location: ISideBarLayoutLocation;
- }>
-> = ({ hasTopBanner, location, children }) => {
- const { handleSetAsideExpanded, isAsideExpanded, asideTitle } = useLayout();
+export const SideBarAside: FC<{
+ hasTopBanner?: boolean;
+ location: ISideBarLayoutLocation;
+}> = ({ hasTopBanner, location }) => {
+ const {
+ setIsRightAsideExpanded,
+ isRightAsideExpanded,
+ rightAsideTitle,
+ setRightAsideRef,
+ } = useLayout();
+ const ref = useRef();
const handleExpand = (e: PressEvent) => {
- if (handleSetAsideExpanded) {
- handleSetAsideExpanded(false);
- }
+ setIsRightAsideExpanded(false);
};
useEffect(() => {
- handleSetAsideExpanded(!!location?.hash);
+ if (!ref.current) return;
+ setRightAsideRef(ref.current);
+ }, [ref.current]);
+
+ useEffect(() => {
+ setIsRightAsideExpanded(!!location?.hash);
}, [location?.hash]);
return (
@@ -37,13 +44,13 @@ export const SideBarAside: FC<
>
);
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarTree.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarTree.tsx
index 37e6d36520..8189c4f2d7 100644
--- a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarTree.tsx
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarTree.tsx
@@ -109,22 +109,4 @@ export const SideBarTree: FC = ({
>
);
-
- // return (
- //
- // );
- // {children}
- //
- // {!isExpanded ? (
- //
- // ) : (
- // children
- // )}
- //
- //
- // );
};
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarTreeItem.tsx b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarTreeItem.tsx
index b3899a2fb2..44dd1c81c7 100644
--- a/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarTreeItem.tsx
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/components/SideBarTreeItem.tsx
@@ -1,4 +1,4 @@
-import type { FC } from 'react';
+import type { FC, MouseEventHandler } from 'react';
import React, { forwardRef, useMemo } from 'react';
import { useMedia } from 'react-use';
import { listItemClass } from '../sidebar.css';
@@ -41,8 +41,10 @@ export const SideBarTreeItem: FC = ({
}) => {
const { handleSetExpanded, isActiveUrl } = useLayout();
const isMediumDevice = useMedia(breakpoints.md, true);
- const handlePress = (e: PressEvent) => {
- if (!isMediumDevice) handleSetExpanded(false);
+ const handlePress: MouseEventHandler = (e) => {
+ if (!isMediumDevice) {
+ handleSetExpanded(false);
+ }
if (onPress) onPress(e);
};
@@ -51,12 +53,11 @@ export const SideBarTreeItem: FC = ({
}, [component, href]);
return (
-
+
{label}
diff --git a/packages/libs/kode-ui/src/patterns/SideBarLayout/sidebar.css.ts b/packages/libs/kode-ui/src/patterns/SideBarLayout/sidebar.css.ts
index e49011ffe2..2026c9fe73 100644
--- a/packages/libs/kode-ui/src/patterns/SideBarLayout/sidebar.css.ts
+++ b/packages/libs/kode-ui/src/patterns/SideBarLayout/sidebar.css.ts
@@ -10,6 +10,9 @@ import { minHeaderHeight, sideBarWidth } from './styles.css';
export const menuBackdropClass = recipe({
base: [
+ {
+ border: 0,
+ },
responsiveStyle({
xs: {
display: 'flex',
diff --git a/packages/libs/kode-ui/src/patterns/index.ts b/packages/libs/kode-ui/src/patterns/index.ts
index f36a62b614..beafa604ba 100644
--- a/packages/libs/kode-ui/src/patterns/index.ts
+++ b/packages/libs/kode-ui/src/patterns/index.ts
@@ -34,3 +34,12 @@ export type {
ISideBarItemProps,
ISideBarProps,
} from './SideBarLayout';
+
+export {
+ RightAside,
+ RightAsideContent,
+ RightAsideFooter,
+ RightAsideHeader,
+} from './SideBarLayout/components/RightAside';
+
+export type { iRightAsideHeader } from './SideBarLayout/components/RightAside';