diff --git a/package.json b/package.json
index c7f4308..5ddca92 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,6 @@
"semi": false
},
"dependencies": {
- "@headlessui/react": "^2.2.0",
"@ledgerhq/hw-transport-webusb": "^6.29.4",
"@noble/hashes": "^1.5.0",
"@polkadot-api/descriptors": "file:.papi/descriptors",
diff --git a/src/codec-components/EditCodec/CAccountId.tsx b/src/codec-components/EditCodec/CAccountId.tsx
index f20db6f..7587b58 100644
--- a/src/codec-components/EditCodec/CAccountId.tsx
+++ b/src/codec-components/EditCodec/CAccountId.tsx
@@ -1,30 +1,33 @@
-import { PolkadotIdenticon } from "@/components/PolkadotIdenticon"
-import { useSynchronizeInput } from "@/components/useSynchroniseInput"
+import { AccountIdDisplay } from "@/components/AccountIdDisplay"
+import { Button } from "@/components/ui/button"
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "@/components/ui/command"
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover"
import {
accountDetail$,
accounts$,
- getAccountMapKey,
getPublicKey,
} from "@/extension-accounts.state"
import { identity$, isVerified } from "@/identity.state"
+import { cn } from "@/utils/cn"
import { EditAccountId, NOTIN } from "@codec-components"
-import {
- Combobox,
- ComboboxButton,
- ComboboxInput,
- ComboboxOption,
- ComboboxOptions,
-} from "@headlessui/react"
-import {
- getSs58AddressInfo,
- SS58String,
-} from "@polkadot-api/substrate-bindings"
+import { getSs58AddressInfo } from "@polkadot-api/substrate-bindings"
+import { toHex } from "@polkadot-api/utils"
import { state, useStateObservable } from "@react-rxjs/core"
import { combineKeys } from "@react-rxjs/utils"
-import { CheckCircle } from "lucide-react"
+import { Check, ChevronsUpDown } from "lucide-react"
import { FC, useState } from "react"
import { map, switchMap, take } from "rxjs"
-import { twMerge } from "tailwind-merge"
const hintedAccounts$ = state(
combineKeys(
@@ -55,129 +58,114 @@ const hintedAccounts$ = state(
)
export const CAccountId: EditAccountId = ({ value, onValueChanged }) => {
- const [localInput, setLocalInput] = useSynchronizeInput(
- value,
- onValueChanged,
- parseValue,
- )
const accounts = useStateObservable(hintedAccounts$)
- const valueIdentity = useStateObservable(
- identity$(value === NOTIN ? "" : value),
- )
const [query, setQuery] = useState("")
const queryInfo = getSs58AddressInfo(query)
- const filteredAccounts =
- query === ""
- ? Array.from(accounts.values())
- : Array.from(accounts.values()).filter(
- (account) =>
- account.address.toLowerCase().includes(query.toLowerCase()) ||
- (account.name &&
- account.name.toLowerCase().includes(query.toLowerCase())),
- )
+
+ const [open, _setOpen] = useState(false)
+ const setOpen = (value: boolean) => {
+ _setOpen(value)
+ setQuery("")
+ }
+
+ const valueIsNew =
+ value !== NOTIN &&
+ !accounts.has(toHex(getPublicKey(value) ?? new Uint8Array()))
return (
- setLocalInput(v ?? "")}
- onClose={() => setQuery("")}
- immediate
- >
-
- {localInput && (
-
+
+
+
+
+
+
- )}
-
- valueIdentity?.displayName ??
- accounts.get(getAccountMapKey(address))?.name ??
- address
- }
- onChange={(event) => setQuery(event.target.value)}
- />
-
-
- {filteredAccounts.length > 0 ? (
- filteredAccounts.map((account) => (
-
- ))
- ) : queryInfo.isValid ? (
-
- ) : (
-
- The value is not a valid Account ID
-
- )}
-
-
+
+
+
+ The value is not a valid Account ID
+
+
+
+ {Array.from(accounts.entries()).map(([key, account]) => (
+ {
+ onValueChanged(account.address)
+ setOpen(false)
+ }}
+ />
+ ))}
+ {valueIsNew && (
+ setOpen(false)}
+ />
+ )}
+ {queryInfo.isValid && (
+ {
+ onValueChanged(query)
+ setOpen(false)
+ }}
+ />
+ )}
+
+
+
+
+
)
}
-const AccountOption: FC<{ account: string; publicKey: Uint8Array | null }> = ({
- account,
- publicKey,
-}) => {
+const AccountOption: FC<{
+ account: string
+ selected: boolean
+ onSelect: () => void
+}> = ({ account, selected, onSelect }) => {
const details = useStateObservable(accountDetail$(account))
const identity = useStateObservable(identity$(account))
const name = identity?.displayName ?? details?.name
return (
-
-
-
- {name && (
-
- {name}
- {isVerified(identity) && (
-
- )}
-
+
+
- {account}
-
-
-
+ />
+
)
}
-
-const getValidationError = (value: string) => {
- if (value === "") return null
- const { isValid } = getSs58AddressInfo(value)
- return isValid ? null : "Invalid address"
-}
-const parseValue = (value: string): SS58String | NOTIN => {
- if (value.trim() === "") return NOTIN
- if (getValidationError(value)) return NOTIN
- return value
-}
diff --git a/src/components/AccountIdDisplay.tsx b/src/components/AccountIdDisplay.tsx
index 248485f..6c72bec 100644
--- a/src/components/AccountIdDisplay.tsx
+++ b/src/components/AccountIdDisplay.tsx
@@ -21,7 +21,7 @@ export const AccountIdDisplay: FC<{
{name && (
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 36496a2..368839c 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
@@ -30,26 +30,41 @@ const buttonVariants = cva(
variant: "default",
size: "default",
},
- }
+ },
)
export interface ButtonProps
extends React.ButtonHTMLAttributes,
VariantProps {
asChild?: boolean
+ forceSvgSize?: boolean
}
const Button = React.forwardRef(
- ({ className, variant, size, asChild = false, ...props }, ref) => {
+ (
+ {
+ className,
+ variant,
+ size,
+ asChild = false,
+ forceSvgSize = true,
+ ...props
+ },
+ ref,
+ ) => {
const Comp = asChild ? Slot : "button"
return (
)
- }
+ },
)
Button.displayName = "Button"
diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx
index 0ac9af3..f8d3205 100644
--- a/src/components/ui/command.tsx
+++ b/src/components/ui/command.tsx
@@ -14,7 +14,7 @@ const Command = React.forwardRef<
ref={ref}
className={cn(
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
- className
+ className,
)}
{...props}
/>
@@ -45,7 +45,7 @@ const CommandInput = React.forwardRef<
ref={ref}
className={cn(
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
- className
+ className,
)}
{...props}
/>
@@ -88,7 +88,7 @@ const CommandGroup = React.forwardRef<
ref={ref}
className={cn(
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
- className
+ className,
)}
{...props}
/>
@@ -110,13 +110,17 @@ CommandSeparator.displayName = CommandPrimitive.Separator.displayName
const CommandItem = React.forwardRef<
React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
+ React.ComponentPropsWithoutRef & {
+ forceSvgSize?: boolean
+ }
+>(({ className, forceSvgSize = true, ...props }, ref) => (
@@ -132,7 +136,7 @@ const CommandShortcut = ({