Skip to content

Commit a30a0e8

Browse files
authored
Merge pull request #1467 from Bilb/chore/ucs-qa-feedback-2
fix: UCS QA review feedback #2
2 parents 4cbe381 + d00f41f commit a30a0e8

File tree

14 files changed

+154
-162
lines changed

14 files changed

+154
-162
lines changed

ts/components/MemberListItem.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,6 @@ export const MemberListItem = <T extends string>({
378378
active={isSelected}
379379
value={pubkey}
380380
inputName={pubkey}
381-
label=""
382381
inputDataTestId="select-contact"
383382
/>
384383
</StyledCheckContainer>

ts/components/SessionSearchInput.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { LucideIcon } from './icon/LucideIcon';
1414

1515
const StyledSearchInput = styled.div`
1616
height: var(--search-input-height);
17-
background-color: var(--background-secondary-color);
17+
background-color: var(--background-tertiary-color);
1818
width: 100%;
1919
// max width because it doesn't look good on a wide dialog otherwise
2020
max-width: 300px;
@@ -23,8 +23,8 @@ const StyledSearchInput = styled.div`
2323
display: inline-flex;
2424
align-items: center;
2525
flex-shrink: 0;
26-
border-radius: 100px;
2726
padding-inline: var(--margins-sm);
27+
border-radius: 100px;
2828
`;
2929

3030
const StyledInput = styled.input`
@@ -88,8 +88,15 @@ export const SessionSearchInput = ({ searchType }: { searchType: SearchType }) =
8888
? localize('searchContacts').toString()
8989
: localize('search').toString();
9090

91+
const isInMainScreen = searchType === 'global' || searchType === 'create-group';
92+
93+
const backgroundColor = isInMainScreen ? 'transparent' : undefined;
94+
9195
return (
92-
<StyledSearchInput data-testid={isGroupCreationSearch ? 'search-contacts-field' : undefined}>
96+
<StyledSearchInput
97+
data-testid={isGroupCreationSearch ? 'search-contacts-field' : undefined}
98+
style={{ backgroundColor }}
99+
>
93100
<LucideIcon
94101
iconColor="var(--search-bar-icon-color)"
95102
iconSize={iconSize}

ts/components/basic/SessionRadio.tsx

Lines changed: 120 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,97 @@
1-
import { ChangeEvent, SessionDataTestId, SyntheticEvent } from 'react';
1+
import { ChangeEvent, SessionDataTestId, type MouseEventHandler } from 'react';
22

33
import styled, { CSSProperties } from 'styled-components';
44
import { Flex } from './Flex';
55

6-
const StyledButton = styled.button<{ disabled: boolean }>`
6+
const StyledContainer = styled.div<{ disabled: boolean }>`
77
cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')};
88
min-height: 30px;
99
background-color: var(--transparent-color);
1010
`;
1111

12-
const StyledInput = styled.input<{
13-
filledSize: number;
14-
outlineOffset: number;
15-
selectedColor?: string;
12+
const StyledRadioOuter = styled.div<{ $disabled: boolean; $diameterRadioBorder: number }>`
13+
width: ${props => props.$diameterRadioBorder}px;
14+
height: ${props => props.$diameterRadioBorder}px;
15+
border: 1px solid var(--text-primary-color);
16+
border-radius: 50%;
17+
background-color: transparent;
18+
cursor: ${props => (props.$disabled ? 'not-allowed' : 'pointer')};
19+
position: relative;
20+
`;
21+
22+
const StyledSelectedInner = styled.div<{
23+
$disabled: boolean;
24+
$selected: boolean;
25+
$diameterRadioBg: number;
1626
}>`
17-
opacity: 0;
27+
width: ${props => props.$diameterRadioBg}px;
28+
height: ${props => props.$diameterRadioBg}px;
29+
border-radius: 50%;
30+
opacity: ${props => (props.$selected ? 1 : 0)};
31+
background: ${props => (props.$disabled ? 'var(--disabled-color)' : 'var(--primary-color)')};
32+
pointer-events: none;
33+
transition-duration: var(--default-duration);
1834
position: absolute;
19-
width: ${props => props.filledSize + props.outlineOffset}px;
20-
height: ${props => props.filledSize + props.outlineOffset}px;
21-
22-
&:checked + label:before {
23-
background: ${props =>
24-
props.disabled
25-
? 'var(--disabled-color)'
26-
: props.selectedColor
27-
? props.selectedColor
28-
: 'var(--primary-color)'};
29-
}
35+
top: 50%;
36+
left: 50%;
37+
transform: translate(-50%, -50%);
3038
`;
3139

32-
// NOTE (Will): We don't use a transition because it's too slow and creates flickering when changing buttons.
33-
const StyledLabel = styled.label<{
40+
function RadioButton({
41+
disabled,
42+
onClick,
43+
selected,
44+
dataTestId,
45+
diameterRadioBg,
46+
diameterRadioBorder,
47+
style,
48+
ariaLabel,
49+
}: {
50+
selected: boolean;
51+
onClick: MouseEventHandler<HTMLDivElement>;
3452
disabled: boolean;
35-
filledSize: number;
36-
outlineOffset: number;
37-
beforeMargins?: string;
53+
dataTestId: SessionDataTestId | undefined;
54+
diameterRadioBg: number;
55+
diameterRadioBorder: number;
56+
style?: CSSProperties;
57+
ariaLabel?: string;
58+
}) {
59+
// clickHandler is on the parent button, so we need to skip this input while pressing Tab
60+
return (
61+
<StyledRadioOuter
62+
onClick={onClick}
63+
$disabled={disabled}
64+
tabIndex={-1}
65+
data-testid={dataTestId}
66+
$diameterRadioBorder={diameterRadioBorder}
67+
style={style}
68+
aria-label={ariaLabel}
69+
>
70+
<StyledSelectedInner
71+
$disabled={disabled}
72+
$selected={selected}
73+
$diameterRadioBg={diameterRadioBg}
74+
/>
75+
</StyledRadioOuter>
76+
);
77+
}
78+
79+
// NOTE (): We don't use a transition because it's too slow and creates flickering when changing buttons.
80+
const StyledLabel = styled.label<{
81+
$disabled: boolean;
3882
}>`
3983
cursor: pointer;
40-
color: ${props => (props.disabled ? 'var(--disabled-color)' : 'var(--text-primary-color)')};
41-
42-
&:before {
43-
content: '';
44-
display: inline-block;
45-
border-radius: 100%;
46-
47-
padding: ${props => props.filledSize}px;
48-
border: none;
49-
outline: 1px solid currentColor; /* CSS variables don't work here */
50-
outline-offset: ${props => props.outlineOffset}px;
51-
${props => props.beforeMargins && `margin: ${props.beforeMargins};`};
52-
}
84+
color: ${props => (props.$disabled ? 'var(--disabled-color)' : 'var(--text-primary-color)')};
85+
margin-inline-end: var(--margins-sm);
5386
`;
5487

5588
type SessionRadioProps = {
56-
label: string;
89+
label?: string;
5790
value: string;
5891
active: boolean;
5992
inputName?: string;
60-
beforeMargins?: string;
6193
onClick?: (value: string) => void;
6294
disabled?: boolean;
63-
radioPosition?: 'left' | 'right';
6495
style?: CSSProperties;
6596
labelDataTestId?: SessionDataTestId;
6697
inputDataTestId?: SessionDataTestId;
@@ -69,31 +100,28 @@ type SessionRadioProps = {
69100
export const SessionRadio = (props: SessionRadioProps) => {
70101
const {
71102
label,
72-
inputName,
73103
value,
74104
active,
75105
onClick,
76-
beforeMargins,
77106
disabled = false,
78-
radioPosition = 'left',
79107
style,
80108
labelDataTestId,
81109
inputDataTestId,
82110
} = props;
83111

84-
const clickHandler = (e: SyntheticEvent<any>) => {
112+
const clickHandler = (e: React.MouseEvent<any> | React.KeyboardEvent<any>) => {
85113
if (!disabled && onClick) {
86114
// let something else catch the event if our click handler is not set
87115
e.stopPropagation();
88116
onClick(value);
89117
}
90118
};
91119

92-
const filledSize = 15 / 2;
93-
const outlineOffset = 2;
120+
const diameterRadioBorder = 26;
121+
const diameterRadioBg = 20;
94122

95123
return (
96-
<StyledButton
124+
<StyledContainer
97125
onKeyDown={e => {
98126
if (e.code === 'Space') {
99127
clickHandler(e);
@@ -104,112 +132,77 @@ export const SessionRadio = (props: SessionRadioProps) => {
104132
>
105133
<Flex
106134
$container={true}
107-
$flexDirection={radioPosition === 'left' ? 'row' : 'row-reverse'}
108-
$justifyContent={radioPosition === 'left' ? 'flex-start' : 'flex-end'}
109-
style={{ ...style, position: 'relative' }}
135+
$flexDirection={'row'}
136+
$justifyContent={'flex-start'}
137+
style={{ ...style, alignItems: 'center', justifyContent: 'space-between' }}
110138
>
111-
<StyledInput
112-
type="radio"
113-
name={inputName || ''}
114-
value={value}
115-
aria-checked={active}
116-
checked={active}
117-
onChange={clickHandler}
118-
tabIndex={-1} // clickHandler is on the parent button, so we need to skip this input while pressing Tab
119-
filledSize={filledSize * 2}
120-
outlineOffset={outlineOffset}
121-
disabled={disabled}
122-
data-testid={inputDataTestId}
123-
/>
124-
<StyledLabel
125-
role="button"
139+
{label ? (
140+
<StyledLabel
141+
role="button"
142+
onClick={clickHandler}
143+
aria-label={label}
144+
$disabled={disabled}
145+
data-testid={labelDataTestId}
146+
>
147+
{label}
148+
</StyledLabel>
149+
) : null}
150+
151+
<RadioButton
152+
selected={active}
126153
onClick={clickHandler}
127-
filledSize={filledSize - 1}
128-
outlineOffset={outlineOffset}
129-
beforeMargins={beforeMargins}
130-
aria-label={label}
131154
disabled={disabled}
132-
data-testid={labelDataTestId}
133-
>
134-
{label}
135-
</StyledLabel>
155+
dataTestId={inputDataTestId}
156+
diameterRadioBorder={diameterRadioBorder}
157+
diameterRadioBg={diameterRadioBg}
158+
/>
136159
</Flex>
137-
</StyledButton>
160+
</StyledContainer>
138161
);
139162
};
140163

141-
const StyledInputOutlineSelected = styled(StyledInput)`
142-
color: ${props => (props.disabled ? 'var(--disabled-color)' : 'var(--text-primary-color)')};
143-
144-
label:before,
145-
label:before {
146-
outline: none;
147-
}
148-
149-
&:checked + label:before {
150-
outline: 1px solid currentColor;
151-
}
152-
`;
153-
const StyledLabelOutlineSelected = styled(StyledLabel)<{ selectedColor: string }>`
154-
&:before {
155-
background: ${props =>
156-
props.disabled
157-
? 'var(--disabled-color)'
158-
: props.selectedColor
159-
? props.selectedColor
160-
: 'var(--primary-color)'};
161-
outline: 1px solid transparent; /* CSS variables don't work here */
162-
}
163-
`;
164-
165164
/**
166-
* Keeping this component here so we can reuse the `StyledInput` and `StyledLabel` defined locally rather than exporting them
165+
* This is slightly different that the classic SessionRadio as this one has
166+
* - no padding between the selected background and the border,
167+
* - they all have a background color (even when not selected), but the border is present on the selected one
168+
*
169+
* Keeping it here so we don't have to export
167170
*/
168171
export const SessionRadioPrimaryColors = (props: {
169172
value: string;
170173
active: boolean;
171-
inputName?: string;
172174
onClick: (value: string) => void;
173-
ariaLabel?: string;
175+
ariaLabel: string;
174176
color: string; // by default, we use the theme accent color but for the settings screen we need to be able to force it
175-
disabled?: boolean;
176177
}) => {
177-
const { inputName, value, active, onClick, color, ariaLabel, disabled = false } = props;
178+
const { value, active, onClick, color, ariaLabel } = props;
178179

179180
function clickHandler(e: ChangeEvent<any>) {
180181
e.stopPropagation();
181182
onClick(value);
182183
}
183184

184-
const filledSize = 31 / 2;
185-
const outlineOffset = 5;
185+
// this component has no padding between the selected background and the border
186+
const diameterRadioBorder = 26;
187+
const diameterRadioBg = 22;
188+
189+
const overriddenColorsVars = {
190+
'--primary-color': color,
191+
'--text-primary-color': active ? undefined : 'transparent',
192+
} as React.CSSProperties;
186193

187194
return (
188195
<Flex $container={true} padding="0 0 5px 0">
189-
<StyledInputOutlineSelected
190-
type="radio"
191-
name={inputName || ''}
192-
value={value}
193-
aria-checked={active}
194-
checked={active}
195-
onChange={clickHandler}
196-
filledSize={filledSize}
197-
outlineOffset={outlineOffset}
198-
selectedColor={color}
199-
aria-label={ariaLabel}
200-
disabled={disabled}
201-
/>
202-
203-
<StyledLabelOutlineSelected
204-
role="button"
196+
<RadioButton
197+
selected={true}
205198
onClick={clickHandler}
206-
selectedColor={color}
207-
filledSize={filledSize}
208-
outlineOffset={outlineOffset}
209-
disabled={disabled}
210-
>
211-
{''}
212-
</StyledLabelOutlineSelected>
199+
disabled={false}
200+
dataTestId={undefined}
201+
diameterRadioBorder={diameterRadioBorder}
202+
diameterRadioBg={diameterRadioBg}
203+
style={overriddenColorsVars}
204+
ariaLabel={ariaLabel}
205+
/>
213206
</Flex>
214207
);
215208
};

0 commit comments

Comments
 (0)