diff --git a/app/css/interceptor.css b/app/css/interceptor.css index f2df2378..dcf22ff2 100644 --- a/app/css/interceptor.css +++ b/app/css/interceptor.css @@ -415,6 +415,16 @@ a.dropdown-item.is-active, button.dropdown-item.is-active { .card-header-icon { background-color: transparent; color: var(--text-color); + + .icon:has(svg[aria-label=chevron-icon]) { + width: 1rem; + height: 1rem; + transition: transform 200ms; + + .card-header:has(+ .card-content) & { + transform: rotateX(180deg); + } + } } .card-header-icon:disabled { @@ -1721,13 +1731,14 @@ header:has(form[role='search']) h1 { } .multiline-card { - --bg-color: #484848; + --bg-color: transparent; --button-color: #77738ccc; --image-size: 2.25rem; - --min-text-width: 3ch; + --min-text-width: 0; --pad-x: 0; --pad-y: 0; --gap-x: 0.5rem; + --gap-y: 0.0625rem; --edge-roundness: 3px; font: inherit; @@ -1735,12 +1746,12 @@ header:has(form[role='search']) h1 { grid-template-columns: [left] minmax(0, min-content) [data] minmax(0, max-content) [right]; grid-template-rows: [top] min-content [sub] min-content [bottom]; column-gap: var(--gap-x); - row-gap: 2px; + row-gap: var(--gap-y); padding-block: var(--pad-y); padding-inline: var(--pad-x); background-color: var(--bg-color); border-radius: var(--edge-roundness); - min-width: calc(var(--min-text-width) + var(--image-size) + (var(-pad-x) * 2) + var(--gap-x)); + min-width: calc(var(--min-text-width) + var(--image-size) + (var(--pad-x) * 2) + var(--gap-x)); data { line-height: 1em; @@ -1754,8 +1765,8 @@ header:has(form[role='search']) h1 { background: var(--bg-color); border: 0 none; padding: 0; - cursor: pointer; + &:not(:disabled) { cursor: pointer } &:hover, &:focus { background: var(--bg-color) } } @@ -1794,7 +1805,13 @@ header:has(form[role='search']) h1 { } } - > data { grid-area: top / left / bottom / right } + > data { + grid-area: top / left / bottom / right; + + &:not(:has(+:disabled)) { + .multiline-card:hover &, .multiline-card:focus-within & { visibility: hidden } + } + } > button { grid-area: top / left / bottom / right; @@ -1802,10 +1819,13 @@ header:has(form[role='search']) h1 { align-items: baseline; grid-template-columns: minmax(0, 1fr) min-content; background-color: var(--bg-color); - opacity: 0; outline: none; + position: relative; + visibility: hidden; - &:is(.multiline-card:hover *, .multiline-card:focus-within *) { opacity: 1 } + &:not(:disabled) { + .multiline-card:hover &, .multiline-card:focus-within & { visibility: visible } + } &:hover, &:focus { > span { diff --git a/app/ts/components/pages/InterceptorAccess.tsx b/app/ts/components/pages/InterceptorAccess.tsx index 5979c8db..0f7e86bf 100644 --- a/app/ts/components/pages/InterceptorAccess.tsx +++ b/app/ts/components/pages/InterceptorAccess.tsx @@ -17,6 +17,7 @@ import { Page } from '../../types/exportedSettingsTypes.js' import { ReadonlySignal, useComputed, useSignal } from '@preact/signals' import { RpcEntries } from '../../types/rpc.js' import { ModifyAddressWindowState } from '../../types/visualizer-types.js' +import { ChevronIcon } from '../subcomponents/icons.js' function Title({ icon, title} : {icon: string | undefined, title: string}) { return @@ -52,7 +53,7 @@ function AssociatedTogether({ associatedAddresses, renameAddressCallBack }: { as }
{ !showLogs diff --git a/app/ts/components/pages/PersonalSign.tsx b/app/ts/components/pages/PersonalSign.tsx index 0de71fc8..9f46cf07 100644 --- a/app/ts/components/pages/PersonalSign.tsx +++ b/app/ts/components/pages/PersonalSign.tsx @@ -19,7 +19,7 @@ import { QuarantineReasons } from '../simulationExplaining/Transactions.js' import { GnosisSafeVisualizer } from '../simulationExplaining/customExplainers/GnosisSafeVisualizer.js' import { EditEnsNamedHashCallBack } from '../subcomponents/ens.js' import { ViewSelector, ViewSelector as Viewer } from '../subcomponents/ViewSelector.js' -import { XMarkIcon } from '../subcomponents/icons.js' +import { ChevronIcon, XMarkIcon } from '../subcomponents/icons.js' import { TransactionInput } from '../subcomponents/ParsedInputData.js' import { ErrorComponent } from '../subcomponents/Error.js' import { PendingTransactionOrSignableMessage } from '../../types/accessRequest.js' @@ -358,7 +358,7 @@ function ExtraDetails({ visualizedPersonalSignRequest, renameAddressCallBack }: Extra details { !showSummary @@ -387,7 +387,7 @@ function RawMessage({ visualizedPersonalSignRequest }: ExtraDetailsCardParams) { Raw message { !showSummary diff --git a/app/ts/components/simulationExplaining/SimulationSummary.tsx b/app/ts/components/simulationExplaining/SimulationSummary.tsx index 79d8ce07..ac94aaf5 100644 --- a/app/ts/components/simulationExplaining/SimulationSummary.tsx +++ b/app/ts/components/simulationExplaining/SimulationSummary.tsx @@ -18,7 +18,7 @@ import { Website } from '../../types/websiteAccessTypes.js' import { extractTokenEvents } from '../../background/metadataUtils.js' import { EditEnsNamedHashCallBack } from '../subcomponents/ens.js' import { EnrichedEthereumInputData } from '../../types/EnrichedEthereumData.js' -import { XMarkIcon } from '../subcomponents/icons.js' +import { ChevronIcon, XMarkIcon } from '../subcomponents/icons.js' import { TransactionInput } from '../subcomponents/ParsedInputData.js' import { sendPopupMessageToBackgroundPage } from '../../background/backgroundUtils.js' import { IntegerInput } from '../subcomponents/AutosizingInput.js' @@ -428,7 +428,7 @@ export function TokenLogAnalysisCard({ simTx, renameAddressCallBack }: TokenLogA { tokenResults.length === 0 ? `No ${ tokenEventsPlural }` : `${ tokenResults.length > 1 ? `${ upperCaseFirstCharacter(convertNumberToCharacterRepresentationIfSmallEnough(tokenResults.length)) } ${ tokenEventsPlural }` : tokenEventsSingular }` } { !showLogs @@ -463,7 +463,7 @@ export function NonTokenLogAnalysisCard({ simTx, addressMetaData, renameAddressC { nonTokenLogs.length === 0 ? 'No non-token events' : `${ upperCaseFirstCharacter(convertNumberToCharacterRepresentationIfSmallEnough(nonTokenLogs.length)) } non-token event${ nonTokenLogs.length > 1 ? 's' : '' }` } { !showLogs @@ -510,7 +510,7 @@ export function TransactionsAccountChangesCard({ simTx, renameAddressCallBack, a { numberOfChanges === 0 ? 'No changes in accounts' : `${ upperCaseFirstCharacter(convertNumberToCharacterRepresentationIfSmallEnough(numberOfChanges)) } account${ numberOfChanges > 1 ? 's' : '' } changing` } { !showSummary @@ -698,7 +698,7 @@ export function SimulationSummary(param: SimulationSummaryParams) { { notOwnAddresses.length === 0 ? 'No changes in other accounts' : `${ upperCaseFirstCharacter(convertNumberToCharacterRepresentationIfSmallEnough(notOwnAddresses.length)) } other account${ notOwnAddresses.length > 1 ? 's' : '' } changing` } { !showOtherAccountChanges @@ -755,7 +755,7 @@ export function RawTransactionDetailsCard({ transaction, renameAddressCallBack, Raw transaction information { !showSummary diff --git a/app/ts/components/subcomponents/MultilineCard.tsx b/app/ts/components/subcomponents/MultilineCard.tsx index ca78b88f..2eff04ab 100644 --- a/app/ts/components/subcomponents/MultilineCard.tsx +++ b/app/ts/components/subcomponents/MultilineCard.tsx @@ -4,88 +4,135 @@ import { Tooltip, TooltipConfig } from './Tooltip.js' import { clipboardCopy } from './clipboardcopy.js' import { CopyIcon } from './icons.js' -export type CardIcon = { - component: () => JSX.Element - onClick?: () => void - tooltipText?: string -} - export type MultilineCardProps = { - icon: CardIcon + icon: ActionableIconProps label: ActionableTextProps note: ActionableTextProps style?: JSX.CSSProperties } export const MultilineCard = ({ icon, label, note, style }: MultilineCardProps) => { + return ( + + ) +} + +export type ActionableIconProps = { + onClick: 'clipboard-copy' + icon: () => JSX.Element + copyValue?: string + copySuccessMessage: string + hintText?: string +} | { + onClick: JSX.MouseEventHandler