Skip to content

Commit 9e4286f

Browse files
committed
Update all Send icons to Phosphor
This requires some more general refactoring to icons in a few other places to fully support Phosphor icons as an option for source icons everywhere.
1 parent 6076b4f commit 9e4286f

File tree

8 files changed

+122
-90
lines changed

8 files changed

+122
-90
lines changed

src/components/common/icon-button.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const IconButton = styled((p: {
99
className?: string,
1010
title: string,
1111
icon: IconProp | IconKey,
12+
iconSize?: string,
1213
disabled?: boolean,
1314
fixedWidth?: boolean,
1415
tabIndex?: number,
@@ -26,11 +27,12 @@ export const IconButton = styled((p: {
2627
{ Array.isArray(p.icon)
2728
? <Icon
2829
icon={p.icon}
30+
size={p.iconSize}
2931
fixedWidth={p.fixedWidth ? true : false}
3032
/>
3133
: <PhosphorIcon
3234
icon={p.icon as IconKey}
33-
size='1.25em'
35+
size={p.iconSize || '1.25em'}
3436
/>
3537
}
3638
</UnstyledButton>

src/components/common/search-box.tsx

Lines changed: 0 additions & 61 deletions
This file was deleted.
Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
import * as React from 'react';
22

33
import { styled } from '../../styles';
4-
import { SourceIcons, Icon } from '../../icons';
4+
import { SourceIcons, Icon, PhosphorIcon, IconKey } from '../../icons';
55

66
import { TrafficSource } from '../../model/http/sources';
77

88
export const SourceIcon = styled(({ source, className }: {
99
source: TrafficSource,
1010
className?: string
11-
}) => source.icon !== SourceIcons.Unknown
12-
? <Icon
13-
className={className}
14-
title={source.summary}
15-
{...source.icon}
16-
/>
17-
: null
18-
)`
11+
}) => {
12+
if (source.icon === SourceIcons.Unknown) return null;
13+
14+
const iconId = source.icon.icon;
15+
16+
if (Array.isArray(iconId)) {
17+
return <Icon
18+
className={className}
19+
title={source.summary}
20+
{...source.icon}
21+
icon={iconId}
22+
/>
23+
} else {
24+
return <PhosphorIcon
25+
className={className}
26+
alt={source.summary}
27+
size='1.25em'
28+
{...source.icon}
29+
icon={iconId as IconKey}
30+
/>
31+
}
32+
})`
1933
margin-left: 8px;
2034
`;

src/components/intercept/connected-sources.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ export const ConnectedSources = styled((props: { activeSources: TrafficSource[],
2525
props.activeSources.length ?
2626
props.activeSources.map((source) =>
2727
<ConnectedSource key={source.ua} title={source.ua}>
28-
<Icon {...source.icon} fixedWidth={true} />
28+
<Icon
29+
{...source.icon}
30+
size='1.1em'
31+
fixedWidth={true}
32+
/>
2933
{ source.summary }
3034
</ConnectedSource>
3135
)

src/components/intercept/intercept-page.tsx

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import { MANUAL_INTERCEPT_ID } from '../../model/interception/interceptors';
1313

1414
import { ConnectedSources } from './connected-sources';
1515
import { InterceptOption } from './intercept-option';
16-
import { SearchBox } from '../common/search-box';
16+
import { TextInput } from '../common/inputs';
17+
import { IconButton } from '../common/icon-button';
1718

1819
interface InterceptPageProps {
1920
className?: string;
@@ -86,12 +87,50 @@ const InterceptInstructions = styled.div`
8687
}
8788
`;
8889

89-
const InterceptSearchBox = styled(SearchBox).attrs(() => ({
90-
autoFocus: true,
91-
placeholder: 'Browsers, mobile, docker...',
92-
'aria-label': "Filter the list of intercept options below",
93-
iconSize: '2x'
94-
}))`
90+
const SearchInput = styled(TextInput)`
91+
width: 100%;
92+
padding: 15px;
93+
box-sizing: border-box;
94+
95+
box-shadow: inset 0 2px 4px 1px rgba(0, 0, 0, ${p => p.theme.boxShadowAlpha / 2});
96+
97+
font-size: ${p => p.theme.headingSize};
98+
`;
99+
100+
const ClearSearchButton = styled(IconButton)`
101+
position: absolute;
102+
103+
right: 15px;
104+
top: 50%;
105+
transform: translateY(-50%);
106+
cursor: pointer;
107+
`;
108+
109+
const SearchBox = styled((props: {
110+
className?: string,
111+
value: string,
112+
onSearch: (input: string) => void
113+
}) =>
114+
<div className={props.className}>
115+
<SearchInput
116+
autoFocus={true}
117+
value={props.value}
118+
placeholder='Browsers, mobile, docker...'
119+
aria-label='Filter the list of intercept options below'
120+
onChange={(e) => props.onSearch(e.currentTarget.value)}
121+
/>
122+
{ !!props.value &&
123+
<ClearSearchButton
124+
icon={['fas', 'times']}
125+
iconSize={'2x'}
126+
onClick={() => props.onSearch('')}
127+
title='Clear search input'
128+
/>
129+
}
130+
</div>
131+
)`
132+
position: relative;
133+
95134
@media (min-width: ${NARROW_LAYOUT_BREAKPOINT}px) {
96135
margin: 20px 0 0;
97136
}
@@ -138,7 +177,7 @@ class InterceptPage extends React.Component<InterceptPageProps> {
138177
Click an option below to connect a traffic source, or
139178
search for connectors that could work for you:
140179
</p>
141-
<InterceptSearchBox
180+
<SearchBox
142181
value={this.filter || ''}
143182
onSearch={this.onSearchInput}
144183
/>

src/components/view/http/http-details-footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const SendButton = observer((p: {
9393
isPaidUser: boolean,
9494
onClick: () => void
9595
}) => <IconButton
96-
icon={['far', 'paper-plane']}
96+
icon='PaperPlaneTilt'
9797
onClick={p.onClick}
9898
title={p.isPaidUser
9999
? `Resend this request (${Ctrl}+r)`

src/icons.tsx

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ export const PhosphorIcon = React.memo((props: { icon: IconKey } & PhosphorIconP
2828
const PIcon = Icons[props.icon];
2929

3030
return <PIcon
31-
className='phosphor-icon'
3231
{...otherProps}
32+
className={'phosphor-icon ' + (props.className || '')}
3333
/>;
3434
});
3535

@@ -215,7 +215,7 @@ library.add(
215215
);
216216

217217
export interface IconProps {
218-
icon: ExtendedIconProp;
218+
icon: ExtendedIconProp | IconKey;
219219
color: string;
220220
size?: SizeProp;
221221
}
@@ -281,18 +281,52 @@ export const SourceIcons = {
281281
Unknown: { icon: ['fas', 'question'], color: '#888' }
282282
} as const;
283283

284-
import { FontAwesomeIcon, Props as FAIProps } from '@fortawesome/react-fontawesome';
284+
import * as FA from '@fortawesome/react-fontawesome';
285285
type ExtendedIconProp = IconProp | readonly ['fac', string] | readonly [IconPrefix, IconName];
286-
export const Icon = React.memo(
287-
FontAwesomeIcon as (props: Omit<FAIProps, 'icon'> & {
286+
const FAIcon = React.memo(
287+
FA.FontAwesomeIcon as (props: Omit<FA.FontAwesomeIconProps, 'icon'> & {
288288
icon: ExtendedIconProp,
289289
onClick?: (event: React.MouseEvent) => void,
290290
onKeyPress?: (event: React.KeyboardEvent) => void
291291
}) => JSX.Element
292292
);
293+
294+
export const Icon = (props: {
295+
icon: ExtendedIconProp | IconKey,
296+
onClick?: (event: React.MouseEvent) => void,
297+
onKeyPress?: (event: React.KeyboardEvent) => void,
298+
299+
spin?: boolean,
300+
color?: string,
301+
size?: string,
302+
fixedWidth?: boolean,
303+
className?: string,
304+
title?: string
305+
}): JSX.Element => {
306+
if (Array.isArray(props.icon)) {
307+
return <FAIcon
308+
{...props}
309+
size={props.size as FA.FontAwesomeIconProps['size']}
310+
icon={props.icon as ExtendedIconProp}
311+
/>
312+
} else {
313+
return <PhosphorIcon
314+
icon={props.icon as IconKey}
315+
316+
onClick={props.onClick}
317+
onKeyPress={props.onKeyPress}
318+
319+
color={props.color}
320+
size={props.size || '1.25em'}
321+
className={props.className}
322+
alt={props.title}
323+
/>
324+
}
325+
};
326+
293327
export type { ExtendedIconProp as IconProp, SizeProp };
294328

295-
export const SuggestionIcon = styled(Icon).attrs(() => ({
329+
export const SuggestionIcon = styled(FAIcon).attrs(() => ({
296330
icon: ['fas', 'lightbulb']
297331
}))`
298332
margin: 0 6px;
@@ -309,7 +343,7 @@ export const suggestionIconHtml = iconHtml(
309343
}
310344
);
311345

312-
export const WarningIcon = styled(Icon).attrs(() => ({
346+
export const WarningIcon = styled(FAIcon).attrs(() => ({
313347
icon: ['fas', 'exclamation-triangle']
314348
}))`
315349
margin: 0 6px;
@@ -326,7 +360,7 @@ export const warningIconHtml = iconHtml(
326360
}
327361
);
328362

329-
export const ArrowIcon = styled(Icon).attrs(() => ({
363+
export const ArrowIcon = styled(FAIcon).attrs(() => ({
330364
fixedWidth: true,
331365
icon: ['fas', 'arrow-left']
332366
}))`

src/model/http/sources.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ export const MANUALLY_SENT_SOURCE = {
156156
summary: 'HTTP Toolkit (Send)',
157157
description: 'Sent manually from HTTP Toolkit',
158158
icon: {
159-
icon: ['far', 'paper-plane'],
159+
icon: 'PaperPlaneTilt',
160160
color: popColor
161161
}
162162
};

0 commit comments

Comments
 (0)