Skip to content

Commit 50395e9

Browse files
committed
Merge branch 'frontend-revamp-tx-details'
2 parents eba42d7 + 5cf8364 commit 50395e9

File tree

26 files changed

+815
-483
lines changed

26 files changed

+815
-483
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
- Update decimal formatting for stablecoin transactions
3232
- Change block explorer to mempool.space
3333
- Integrate Bitrefill and add spending section
34+
- Revamp transaction detail dialog
3435

3536
## v4.48.8
3637
- Bundle BitBox02 Nova firmware version v9.23.3
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
.accordion {
2+
width: 100%;
3+
}
4+
5+
.header {
6+
display: flex;
7+
align-items: center;
8+
justify-content: space-between;
9+
width: 100%;
10+
padding: 0;
11+
background-color: var(--background-secondary);
12+
border: none;
13+
cursor: pointer;
14+
font-size: var(--size-default);
15+
font-family: var(--font-family);
16+
color: var(--color-default);
17+
text-align: left;
18+
}
19+
20+
.header:focus {
21+
outline: none;
22+
}
23+
24+
.title {
25+
flex: 1;
26+
font-weight: 600;
27+
}
28+
29+
.chevron {
30+
flex-shrink: 0;
31+
transform: rotate(90deg);
32+
transition: transform 0.2s ease-out;
33+
}
34+
35+
.chevron.expanded {
36+
transform: rotate(270deg);
37+
}
38+
39+
.content {
40+
padding: var(--space-half) 0;
41+
padding-top: calc(var(--space-half) + var(--space-quarter));
42+
background-color: var(--background-secondary);
43+
color: var(--color-default);
44+
font-size: var(--size-default);
45+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* Copyright 2025 Shift Crypto AG
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { useState, ReactNode } from 'react';
18+
import { ChevronRightDark } from '@/components/icon/icon';
19+
import styles from './accordion.module.css';
20+
21+
type TAccordionProps = {
22+
title: string;
23+
className?: string;
24+
isOpen?: boolean;
25+
onToggle?: () => void;
26+
defaultOpen?: boolean;
27+
children: ReactNode;
28+
};
29+
30+
export const Accordion = ({
31+
title,
32+
className = '',
33+
isOpen,
34+
onToggle,
35+
defaultOpen = false,
36+
children,
37+
}: TAccordionProps) => {
38+
const [internalOpen, setInternalOpen] = useState<boolean>(defaultOpen);
39+
40+
const isControlled = isOpen !== undefined && onToggle !== undefined;
41+
const currentOpen = isControlled ? isOpen : internalOpen;
42+
43+
const handleToggle = () => {
44+
if (isControlled) {
45+
onToggle();
46+
} else {
47+
setInternalOpen(prev => !prev);
48+
}
49+
};
50+
51+
return (
52+
<div className={`${styles.accordion || ''} ${className}`}>
53+
<button
54+
className={styles.header}
55+
onClick={handleToggle}
56+
aria-expanded={currentOpen}
57+
type="button"
58+
>
59+
<span className={styles.title}>{title}</span>
60+
<ChevronRightDark
61+
className={`${styles.chevron || ''} ${currentOpen ? styles.expanded || '' : ''}`}
62+
width={24}
63+
height={24}
64+
/>
65+
</button>
66+
{currentOpen && (
67+
<div className={styles.content}>
68+
{children}
69+
</div>
70+
)}
71+
</div>
72+
);
73+
};

frontends/web/src/components/amount/amount-with-unit.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type TAmountWithUnitProps = {
2929
sign?: string;
3030
alwaysShowAmounts?: boolean;
3131
convertToFiat?: boolean;
32+
unitClassName?: string;
3233
};
3334

3435
export const AmountWithUnit = ({
@@ -37,7 +38,8 @@ export const AmountWithUnit = ({
3738
enableRotateUnit: rotateUnit,
3839
sign,
3940
convertToFiat,
40-
alwaysShowAmounts = false
41+
alwaysShowAmounts = false,
42+
unitClassName = ''
4143
}: TAmountWithUnitProps) => {
4244
const { rotateDefaultCurrency, defaultCurrency, rotateBtcUnit } = useContext(RatesContext);
4345

@@ -72,7 +74,7 @@ export const AmountWithUnit = ({
7274
/>
7375
) : '---';
7476

75-
const amountUnit = <AmountUnit unit={displayedUnit} rotateUnit={enableClick ? onClick : undefined}/>;
77+
const amountUnit = <AmountUnit unit={displayedUnit} rotateUnit={enableClick ? onClick : undefined} className={unitClassName}/>;
7678

7779
if (tableRow) {
7880
return (
@@ -98,11 +100,12 @@ export const AmountWithUnit = ({
98100
type TAmountUnitProps = {
99101
rotateUnit?: () => Promise<void>;
100102
unit: ConversionUnit | CoinUnit;
103+
className?: string;
101104
};
102105

103-
export const AmountUnit = ({ rotateUnit, unit }: TAmountUnitProps) => {
106+
export const AmountUnit = ({ rotateUnit, unit, className = '' }: TAmountUnitProps) => {
104107
const classRototable = rotateUnit ? (style.rotatable || '') : '';
105-
const textStyle = `${style.unit || ''} ${classRototable}`;
108+
const textStyle = `${style.unit || ''} ${classRototable} ${className}`;
106109
return (
107110
<span className={textStyle} onClick={rotateUnit}>
108111
{unit}

frontends/web/src/components/copy/Copy.tsx

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,26 @@ type TProps = {
2525
alignRight?: boolean;
2626
borderLess?: boolean;
2727
className?: string;
28+
inputFieldClassName?: string;
29+
buttonClassName?: string;
2830
disabled?: boolean;
2931
flexibleHeight?: boolean;
32+
displayValue?: string;
3033
value: string;
3134
};
3235

33-
export const CopyableInput = ({ alignLeft, alignRight, borderLess, value, className, disabled, flexibleHeight }: TProps) => {
36+
export const CopyableInput = ({
37+
alignLeft,
38+
alignRight,
39+
borderLess,
40+
value,
41+
className,
42+
inputFieldClassName,
43+
buttonClassName,
44+
disabled,
45+
flexibleHeight,
46+
displayValue,
47+
}: TProps) => {
3448
const [success, setSuccess] = useState(false);
3549
const { t } = useTranslation();
3650

@@ -63,7 +77,12 @@ export const CopyableInput = ({ alignLeft, alignRight, borderLess, value, classN
6377

6478
const copy = () => {
6579
if (textAreaRef.current) {
66-
navigator.clipboard.writeText(textAreaRef.current.value);
80+
if (displayValue) {
81+
navigator.clipboard.writeText(value);
82+
} else {
83+
navigator.clipboard.writeText(textAreaRef.current.value);
84+
85+
}
6786
setSuccess(true);
6887
}
6988
};
@@ -78,20 +97,24 @@ export const CopyableInput = ({ alignLeft, alignRight, borderLess, value, classN
7897
disabled={disabled}
7998
readOnly
8099
onFocus={onFocus}
81-
value={value}
100+
value={displayValue ? displayValue : value}
82101
ref={textAreaRef}
83102
rows={1}
84-
className={[
85-
style.inputField,
86-
flexibleHeight && style.flexibleHeight,
87-
alignLeft && style.alignLeft,
88-
alignRight && style.alignRight,
89-
borderLess && style.borderLess,
90-
].join(' ')} />
103+
className={`${style.inputField || ''}
104+
${flexibleHeight ? style.flexibleHeight || '' : ''}
105+
${alignLeft ? style.alignLeft || '' : ''}
106+
${alignRight ? style.alignRight || '' : ''}
107+
${borderLess ? style.borderLess || '' : ''}
108+
${inputFieldClassName ? inputFieldClassName : ''}
109+
`} />
91110
{disabled ? null : (
92111
<button
93112
onClick={copy}
94-
className={[style.button, success && style.success, 'ignore'].join(' ')}
113+
className={`
114+
${style.button || ''}
115+
${success ? style.success || '' : ''}
116+
${buttonClassName ? buttonClassName : ''}
117+
ignore`}
95118
title={t('button.copy')}>
96119
{success ? <Check /> : <Copy />}
97120
</button>

frontends/web/src/components/icon/assets/icons/edit-light.svg

Lines changed: 0 additions & 13 deletions
This file was deleted.

frontends/web/src/components/icon/assets/icons/edit.svg

Lines changed: 0 additions & 13 deletions
This file was deleted.

frontends/web/src/components/icon/assets/icons/save-light.svg

Lines changed: 0 additions & 15 deletions
This file was deleted.

frontends/web/src/components/icon/assets/icons/save.svg

Lines changed: 0 additions & 15 deletions
This file was deleted.

frontends/web/src/components/icon/icon.tsx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ import coinsSVG from './assets/icons/coins.svg';
5151
import creditCardDarkSVG from './assets/icons/credit-card.svg';
5252
import creditCardLightSVG from './assets/icons/credit-card-light.svg';
5353
import deviceSVG from './assets/icons/device.svg';
54-
import editSVG from './assets/icons/edit.svg';
55-
import editLightSVG from './assets/icons/edit-light.svg';
5654
import editActiveSVG from './assets/icons/edit-active.svg';
5755
import ejectIconSVG from './assets/icons/eject.svg';
5856
import ethColorSVG from './assets//eth-color.svg';
@@ -87,8 +85,6 @@ import warningPNG from './assets/icons/warning.png';
8785
import warningOutlinedSVG from './assets/icons/warning-outlined.svg';
8886
import qrCodeDarkSVG from './assets/icons/qr-dark.svg';
8987
import qrCodeLightSVG from './assets/icons/qr-light.svg';
90-
import saveSVG from './assets/icons/save.svg';
91-
import saveLightSVG from './assets/icons/save-light.svg';
9288
import shieldSVG from './assets/icons/shield.svg';
9389
import shieldGreySVG from './assets/icons/shield-gray.svg';
9490
import syncSVG from './assets/icons/sync.svg';
@@ -208,8 +204,6 @@ export const Close = (props: ImgProps) => (<img src={closeSVG} draggable={false}
208204
export const CloseXWhite = (props: ImgProps) => (<img src={closeXWhiteSVG} draggable={false} {...props} />);
209205
export const CloseXDark = (props: ImgProps) => (<img src={closeXDarkSVG} draggable={false} {...props} />);
210206
export const Device = (props: ImgProps) => (<img src={deviceSVG} draggable={false} {...props} />);
211-
export const Edit = (props: ImgProps) => (<img src={editSVG} draggable={false} {...props} />);
212-
export const EditLight = (props: ImgProps) => (<img src={editLightSVG} draggable={false} {...props} />);
213207
export const EditActive = (props: ImgProps) => (<img src={editActiveSVG} draggable={false} {...props} />);
214208
export const Eject = (props: ImgProps) => (<img src={ejectIconSVG} draggable={false} {...props} />);
215209
export const ETHLogo = (props: ImgProps) => (<img src={ethColorSVG} draggable={false} {...props} />);
@@ -237,8 +231,6 @@ export const WalletConnectDefaultLogo = (props: ImgProps) => (<img src={walletCo
237231
export const QRCodeDark = (props: ImgProps) => (<img src={qrCodeDarkSVG} draggable={false} {...props} />);
238232
export const QRCodeLight = (props: ImgProps) => (<img src={qrCodeLightSVG} draggable={false} {...props} />);
239233
export const RedDot = (props: ImgProps) => (<img src={redDotSVG} draggable={false} {...props} />);
240-
export const Save = (props: ImgProps) => (<img src={saveSVG} draggable={false} {...props} />);
241-
export const SaveLight = (props: ImgProps) => (<img src={saveLightSVG} draggable={false} {...props} />);
242234
export const Shield = (props: ImgProps) => (<img src={shieldSVG} draggable={false} {...props} />);
243235
export const ShieldGray = (props: ImgProps) => (<img src={shieldGreySVG} draggable={false} {...props} />);
244236
export const SpinnerRingDark = (props: ImgProps) => (<img src={spinnerRingDarkSVG} draggable={false} {...props} />);

0 commit comments

Comments
 (0)