fixes for Firefox incompatibility with button text and select dropdown
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
9e3e01fecf
commit
8cad0db3b8
@ -4,7 +4,7 @@
|
|||||||
"homepage_url": "https://git.ghostchain.io/ghostchain/ghost-extension-wallet",
|
"homepage_url": "https://git.ghostchain.io/ghostchain/ghost-extension-wallet",
|
||||||
"name": "GHOST Wallet",
|
"name": "GHOST Wallet",
|
||||||
"short_name": "ghost-wallet",
|
"short_name": "ghost-wallet",
|
||||||
"version": "0.0.0",
|
"version": "0.0.1",
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"permissions": ["notifications", "storage", "tabs", "alarms"],
|
"permissions": ["notifications", "storage", "tabs", "alarms"],
|
||||||
"background": {
|
"background": {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"homepage_url": "https://git.ghostchain.io/ghostchain/ghost-extension-wallet",
|
"homepage_url": "https://git.ghostchain.io/ghostchain/ghost-extension-wallet",
|
||||||
"name": "GHOST Wallet",
|
"name": "GHOST Wallet",
|
||||||
"short_name": "ghost-wallet",
|
"short_name": "ghost-wallet",
|
||||||
"version": "0.0.0",
|
"version": "0.0.1",
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"permissions": ["notifications", "storage", "tabs", "alarms"],
|
"permissions": ["notifications", "storage", "tabs", "alarms"],
|
||||||
"background": {
|
"background": {
|
||||||
@ -37,7 +37,7 @@
|
|||||||
},
|
},
|
||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
"id": "{9b4d20ed-b18a-4237-b5d0-ca71c2ce2060}"
|
"id": "{14b458b2-3221-4800-a36f-ae1ad1756ae2}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ghost-wallet",
|
"name": "ghost-wallet",
|
||||||
"version": "0.1.3",
|
"version": "0.1.4",
|
||||||
"description": "Browser extension to manage ghost blockchain light clients.",
|
"description": "Browser extension to manage ghost blockchain light clients.",
|
||||||
"main": "dist/src/index.js",
|
"main": "dist/src/index.js",
|
||||||
"author": "Uncle f4ts0 <f4ts0@ghostchain.io>",
|
"author": "Uncle f4ts0 <f4ts0@ghostchain.io>",
|
||||||
@ -146,6 +146,7 @@
|
|||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"embla-carousel-react": "^8.5.1",
|
"embla-carousel-react": "^8.5.1",
|
||||||
"input-otp": "^1.2.4",
|
"input-otp": "^1.2.4",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"lucide-react": "^0.468.0",
|
"lucide-react": "^0.468.0",
|
||||||
"next-themes": "^0.4.1",
|
"next-themes": "^0.4.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
|
721
pnpm-lock.yaml
721
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -9,13 +9,13 @@ const buttonVariants = cva(
|
|||||||
{
|
{
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: "bg-primary text-primary-foreground hover:bg-foreground hover:text-background",
|
default: "bg-primary text-primary-foreground hover:bg-foreground hover:text-background active:text-primary-foreground",
|
||||||
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-foreground hover:text-secondary",
|
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-foreground hover:text-secondary active:text-secondary-foreground",
|
||||||
ghost: "text-primary hover:bg-accent hover:text-background",
|
ghost: "text-primary hover:bg-accent hover:text-background active:text-primary",
|
||||||
|
|
||||||
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 active:text-destructive-foreground",
|
||||||
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
||||||
link: "text-primary underline-offset-4 hover:underline",
|
link: "text-primary underline-offset-4 hover:underline active:text-primary",
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: "h-10 px-4 py-2",
|
default: "h-10 px-4 py-2",
|
||||||
|
@ -4,7 +4,129 @@ import { Check, ChevronDown, ChevronUp } from "lucide-react"
|
|||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
const Select = SelectPrimitive.Root
|
type SafeSelectProps = React.ComponentProps<typeof SelectPrimitive.Root> & {
|
||||||
|
debounceMs?: number;
|
||||||
|
leaveGraceMs?: number;
|
||||||
|
allowCloseAfterItemMs?: number
|
||||||
|
}
|
||||||
|
const Select = ({
|
||||||
|
children,
|
||||||
|
debounceMs = 200,
|
||||||
|
leaveGraceMs = 150,
|
||||||
|
allowCloseAfterItemMs = 250,
|
||||||
|
onOpenChange,
|
||||||
|
onValueChange,
|
||||||
|
open: controlledOpen,
|
||||||
|
...rest
|
||||||
|
}: SafeSelectProps) => {
|
||||||
|
const lastToggleRef = React.useRef<number>(0)
|
||||||
|
const isControlled = controlledOpen !== undefined
|
||||||
|
const [isOpen, setIsOpen] = React.useState<boolean>(false)
|
||||||
|
|
||||||
|
const pointerInside = React.useRef<boolean>(false)
|
||||||
|
const pointerLeaveTimer = React.useRef<number | null>(null)
|
||||||
|
const lastItemActivate = React.useRef<number>(0)
|
||||||
|
|
||||||
|
const handlePointerEnterContent = React.useCallback(() => {
|
||||||
|
pointerInside.current = true
|
||||||
|
if (pointerLeaveTimer.current) {
|
||||||
|
window.clearTimeout(pointerLeaveTimer.current)
|
||||||
|
pointerLeaveTimer.current = null
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handlePointerLeaveContent = React.useCallback(() => {
|
||||||
|
if (pointerLeaveTimer.current) window.clearTimeout(pointerLeaveTimer.current)
|
||||||
|
pointerLeaveTimer.current = window.setTimeout(() => {
|
||||||
|
pointerInside.current = false
|
||||||
|
pointerLeaveTimer.current = null
|
||||||
|
}, leaveGraceMs) as unknown as number
|
||||||
|
}, [leaveGraceMs])
|
||||||
|
|
||||||
|
const handleItemActivate = React.useCallback(() => {
|
||||||
|
lastItemActivate.current = Date.now()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const enhancedChildren = React.Children.map(children, (child) => {
|
||||||
|
if (!React.isValidElement(child)) return child
|
||||||
|
const type = (child.type as any)?.displayName || (child.type as any)?.name
|
||||||
|
|
||||||
|
if (
|
||||||
|
child.type === SelectPrimitive.Content ||
|
||||||
|
type === SelectPrimitive.Content?.displayName
|
||||||
|
) {
|
||||||
|
return React.cloneElement(child, {
|
||||||
|
onPointerEnter: (...args: any[]) => {
|
||||||
|
handlePointerEnterContent()
|
||||||
|
console.log("item enter")
|
||||||
|
const fn = (child.props as any).onPointerEnter
|
||||||
|
if (fn) fn(...args)
|
||||||
|
},
|
||||||
|
onPointerLeave: (...args: any[]) => {
|
||||||
|
handlePointerLeaveContent()
|
||||||
|
console.log("item leave")
|
||||||
|
const fn = (child.props as any).onPointerLeave
|
||||||
|
if (fn) fn(...args)
|
||||||
|
},
|
||||||
|
forceMount: true,
|
||||||
|
...child.props,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
child.type === SelectPrimitive.Item ||
|
||||||
|
type === SelectPrimitive.Item?.displayName
|
||||||
|
) {
|
||||||
|
return React.cloneElement(child, {
|
||||||
|
onPointerDown: (e: PointerEvent | React.PointerEvent) => {
|
||||||
|
handleItemActivate();
|
||||||
|
console.log("item active")
|
||||||
|
const fn = (child.props as any).onPointerDown;
|
||||||
|
if (fn) fn(e);
|
||||||
|
},
|
||||||
|
...child.props,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
})
|
||||||
|
|
||||||
|
const setOpenInterval = React.useCallback(
|
||||||
|
(value: boolean) => {
|
||||||
|
const now = Date.now()
|
||||||
|
if (now - lastToggleRef.current < debounceMs) return
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
if (now - lastItemActivate.current < allowCloseAfterItemMs) {
|
||||||
|
lastToggleRef.current = now
|
||||||
|
if (!isControlled) setIsOpen(false)
|
||||||
|
onOpenChange?.(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (pointerInside.current) return
|
||||||
|
}
|
||||||
|
|
||||||
|
lastToggleRef.current = now
|
||||||
|
if (!isControlled) setIsOpen(value)
|
||||||
|
if (onOpenChange) onOpenChange(value)
|
||||||
|
},
|
||||||
|
[debounceMs, isControlled, onOpenChange, allowCloseAfterItemMs]
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.Root
|
||||||
|
{...rest}
|
||||||
|
open={isControlled ? controlledOpen : isOpen}
|
||||||
|
onOpenChange={setOpenInterval}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
onValueChange?.(value)
|
||||||
|
setIsOpen(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{enhancedChildren}
|
||||||
|
</SelectPrimitive.Root>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const SelectGroup = SelectPrimitive.Group
|
const SelectGroup = SelectPrimitive.Group
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ export const Accounts = () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const [selectedCryptoKeyName, setSelectedCryptoKeyName] = useState<string | undefined>()
|
const [selectedCryptoKeyName, setSelectedCryptoKeyName] = useState<string | undefined>()
|
||||||
const [isPending, setIsPending] = useState<boolean>()
|
const [isPending, setIsPending] = useState<boolean>(false)
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -170,7 +170,7 @@ export const Accounts = () => {
|
|||||||
<Select
|
<Select
|
||||||
disabled={!cryptoKeys || cryptoKeys.length === 0}
|
disabled={!cryptoKeys || cryptoKeys.length === 0}
|
||||||
value={selectedCryptoKeyName}
|
value={selectedCryptoKeyName}
|
||||||
onValueChange={(v) => setSelectedCryptoKeyName(v)}
|
onValueChange={(value) => setSelectedCryptoKeyName(value)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-[235px]" data-testid="accounts-select">
|
<SelectTrigger className="w-[235px]" data-testid="accounts-select">
|
||||||
<SelectValue placeholder="Select Crypto Key" />
|
<SelectValue placeholder="Select Crypto Key" />
|
||||||
|
@ -169,7 +169,6 @@ export function ImportAccounts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onSubmit: SubmitHandler<FormFields> = async (data) => {
|
const onSubmit: SubmitHandler<FormFields> = async (data) => {
|
||||||
console.log("started")
|
|
||||||
let errorOccured = null
|
let errorOccured = null
|
||||||
|
|
||||||
const keynameExists = await rpc.client.getCryptoKey(data.keyname)
|
const keynameExists = await rpc.client.getCryptoKey(data.keyname)
|
||||||
@ -410,10 +409,9 @@ export function ImportAccounts() {
|
|||||||
<FormItem className="mb-4">
|
<FormItem className="mb-4">
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Select
|
<Select
|
||||||
|
{...field}
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
onValueChange={(scheme) => field.onChange(scheme)}
|
onValueChange={(scheme) => field.onChange(scheme)}
|
||||||
name={field.name}
|
|
||||||
value={field.value}
|
|
||||||
>
|
>
|
||||||
<SelectTrigger
|
<SelectTrigger
|
||||||
className={`${field.value ? "text-primary" : "text-muted-foreground"} w-full`}
|
className={`${field.value ? "text-primary" : "text-muted-foreground"} w-full`}
|
||||||
|
Loading…
Reference in New Issue
Block a user