aboutsummaryrefslogtreecommitdiffstats
path: root/packages/renderer/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/renderer/src')
-rw-r--r--packages/renderer/src/components/locationBar/ButtonAdornment.tsx69
-rw-r--r--packages/renderer/src/components/locationBar/GoButton.tsx (renamed from packages/renderer/src/components/locationBar/GoAdornment.tsx)26
-rw-r--r--packages/renderer/src/components/locationBar/LocationInputAdornment.tsx (renamed from packages/renderer/src/components/locationBar/IconAdornment.tsx)28
-rw-r--r--packages/renderer/src/components/locationBar/LocationTextField.tsx14
-rw-r--r--packages/renderer/src/components/locationBar/SecurityLabel.tsx (renamed from packages/renderer/src/components/locationBar/UrlAdornment.tsx)77
-rw-r--r--packages/renderer/src/components/locationBar/UrlOverlay.tsx3
-rw-r--r--packages/renderer/src/components/locationBar/getAlertColor.ts28
7 files changed, 115 insertions, 130 deletions
diff --git a/packages/renderer/src/components/locationBar/ButtonAdornment.tsx b/packages/renderer/src/components/locationBar/ButtonAdornment.tsx
deleted file mode 100644
index 2cf230b..0000000
--- a/packages/renderer/src/components/locationBar/ButtonAdornment.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import InputAdornment from '@mui/material/InputAdornment';
22import { styled } from '@mui/material/styles';
23
24export const NO_LABEL_BUTTON_CLASS_NAME = 'ButtonAdornment-NoLabel';
25
26const ButtonAdornment = styled(InputAdornment, {
27 name: 'ButtonAdornment',
28})(({ theme, position }) => {
29 const { direction } = theme;
30 const left = direction === 'ltr' ? 'start' : 'end';
31 return {
32 ...(position === left
33 ? {
34 marginRight: 2,
35 marginLeft: -8,
36 }
37 : {
38 marginLeft: 2,
39 marginRight: -8,
40 }),
41 '.MuiButton-root': {
42 minWidth: 32,
43 height: 32,
44 paddingLeft: 6,
45 paddingRight: 6,
46 borderRadius: 16,
47 },
48 ...(direction === 'ltr'
49 ? {
50 '.MuiButton-startIcon': {
51 marginLeft: 0,
52 },
53 [`.${NO_LABEL_BUTTON_CLASS_NAME} .MuiButton-startIcon`]: {
54 marginRight: 0,
55 },
56 }
57 : {
58 '.MuiButton-startIcon': {
59 marginRight: 0,
60 marginLeft: theme.spacing(1),
61 },
62 [`.${NO_LABEL_BUTTON_CLASS_NAME} .MuiButton-startIcon`]: {
63 marginLeft: 0,
64 },
65 }),
66 };
67});
68
69export default ButtonAdornment;
diff --git a/packages/renderer/src/components/locationBar/GoAdornment.tsx b/packages/renderer/src/components/locationBar/GoButton.tsx
index f049b8e..32f715e 100644
--- a/packages/renderer/src/components/locationBar/GoAdornment.tsx
+++ b/packages/renderer/src/components/locationBar/GoButton.tsx
@@ -19,25 +19,33 @@
19 */ 19 */
20 20
21import IconGo from '@mui/icons-material/Send'; 21import IconGo from '@mui/icons-material/Send';
22import Button from '@mui/material/Button'; 22import IconButton from '@mui/material/IconButton';
23import React, { MouseEventHandler } from 'react'; 23import React, { MouseEventHandler } from 'react';
24 24
25import ButtonAdornment, { NO_LABEL_BUTTON_CLASS_NAME } from './ButtonAdornment'; 25import LocationInputAdornment from './LocationInputAdornment';
26 26
27export default function GoAdornment({ 27export default function GoButton({
28 onClick, 28 onClick,
29 position,
29}: { 30}: {
30 onClick: MouseEventHandler<HTMLButtonElement>; 31 onClick: MouseEventHandler<HTMLButtonElement>;
32 position: 'start' | 'end';
31}): JSX.Element { 33}): JSX.Element {
32 return ( 34 return (
33 <ButtonAdornment position="end"> 35 <LocationInputAdornment position={position}>
34 <Button 36 <IconButton
35 aria-label="Go" 37 aria-label="Go"
36 color="inherit" 38 color="inherit"
37 startIcon={<IconGo />}
38 className={NO_LABEL_BUTTON_CLASS_NAME}
39 onClick={onClick} 39 onClick={onClick}
40 /> 40 sx={{
41 </ButtonAdornment> 41 minWidth: '32px',
42 height: '32px',
43 paddingX: '6px',
44 borderRadius: '16px',
45 }}
46 >
47 <IconGo fontSize="small" />
48 </IconButton>
49 </LocationInputAdornment>
42 ); 50 );
43} 51}
diff --git a/packages/renderer/src/components/locationBar/IconAdornment.tsx b/packages/renderer/src/components/locationBar/LocationInputAdornment.tsx
index 1a2fa83..a3cd2c5 100644
--- a/packages/renderer/src/components/locationBar/IconAdornment.tsx
+++ b/packages/renderer/src/components/locationBar/LocationInputAdornment.tsx
@@ -21,21 +21,21 @@
21import InputAdornment from '@mui/material/InputAdornment'; 21import InputAdornment from '@mui/material/InputAdornment';
22import { styled } from '@mui/material/styles'; 22import { styled } from '@mui/material/styles';
23 23
24const IconAdornment = styled(InputAdornment, { 24const LocationInputAdornment = styled(InputAdornment, {
25 name: 'IconAdornment', 25 name: 'LocationInputAdornment',
26})(({ theme: { direction }, position }) => { 26})(({ theme: { direction }, position }) => {
27 const left = direction === 'ltr' ? 'start' : 'end'; 27 const left = direction === 'ltr' ? 'start' : 'end';
28 return { 28 const marginStart = -8;
29 ...(position === left 29 const marginEnd = 2;
30 ? { 30 return position === left
31 marginLeft: -2, 31 ? {
32 marginRight: 8, 32 marginLeft: marginStart,
33 } 33 marginRight: marginEnd,
34 : { 34 }
35 marginLeft: 8, 35 : {
36 marginRight: -2, 36 marginLeft: marginEnd,
37 }), 37 marginRight: marginStart,
38 }; 38 };
39}); 39});
40 40
41export default IconAdornment; 41export default LocationInputAdornment;
diff --git a/packages/renderer/src/components/locationBar/LocationTextField.tsx b/packages/renderer/src/components/locationBar/LocationTextField.tsx
index e711abc..3a4f7f5 100644
--- a/packages/renderer/src/components/locationBar/LocationTextField.tsx
+++ b/packages/renderer/src/components/locationBar/LocationTextField.tsx
@@ -26,9 +26,9 @@ import React, { useCallback, useEffect, useState } from 'react';
26 26
27import Service from '../../stores/Service'; 27import Service from '../../stores/Service';
28 28
29import GoAdornment from './GoAdornment'; 29import GoButton from './GoButton';
30import LocationOverlayInput from './LocationOverlayInput'; 30import LocationOverlayInput from './LocationOverlayInput';
31import UrlAdornment from './UrlAdornment'; 31import SecurityLabel from './SecurityLabel';
32import UrlOverlay from './UrlOverlay'; 32import UrlOverlay from './UrlOverlay';
33import splitUrl from './splitUrl'; 33import splitUrl from './splitUrl';
34 34
@@ -113,10 +113,16 @@ function LocationTextField({
113 hiddenLabel 113 hiddenLabel
114 disableUnderline 114 disableUnderline
115 startAdornment={ 115 startAdornment={
116 <UrlAdornment changed={changed} splitResult={splitResult} /> 116 <SecurityLabel
117 changed={changed}
118 splitResult={splitResult}
119 position="start"
120 />
117 } 121 }
118 endAdornment={ 122 endAdornment={
119 changed ? <GoAdornment onClick={() => service?.go(value)} /> : undefined 123 changed ? (
124 <GoButton onClick={() => service?.go(value)} position="end" />
125 ) : undefined
120 } 126 }
121 value={value} 127 value={value}
122 /> 128 />
diff --git a/packages/renderer/src/components/locationBar/UrlAdornment.tsx b/packages/renderer/src/components/locationBar/SecurityLabel.tsx
index 6ede378..6e27e6b 100644
--- a/packages/renderer/src/components/locationBar/UrlAdornment.tsx
+++ b/packages/renderer/src/components/locationBar/SecurityLabel.tsx
@@ -19,68 +19,79 @@
19 */ 19 */
20 20
21import IconHttps from '@mui/icons-material/HttpsOutlined'; 21import IconHttps from '@mui/icons-material/HttpsOutlined';
22import IconHttp from '@mui/icons-material/NoEncryption';
22import IconGlobe from '@mui/icons-material/Public'; 23import IconGlobe from '@mui/icons-material/Public';
23import IconWarning from '@mui/icons-material/Warning'; 24import IconWarning from '@mui/icons-material/Warning';
24import { styled } from '@mui/material'; 25import { styled } from '@mui/material/styles';
25import Button from '@mui/material/Button';
26import React from 'react'; 26import React from 'react';
27 27
28import ButtonAdornment, { NO_LABEL_BUTTON_CLASS_NAME } from './ButtonAdornment'; 28import LocationInputAdornment from './LocationInputAdornment';
29import IconAdornment from './IconAdornment'; 29import getAlertColor from './getAlertColor';
30import type { SplitResult } from './splitUrl'; 30import type { SplitResult } from './splitUrl';
31 31
32const FastColorChangingButton = styled(Button)(({ theme }) => ({ 32const SecurityLabelRoot = styled(LocationInputAdornment, {
33 transition: theme.transitions.create( 33 name: 'SecurityLabel',
34 ['background-color', 'box-shadow', 'border-color'], 34 slot: 'Root',
35 { 35 shouldForwardProp: (prop) => prop !== 'alert',
36 duration: theme.transitions.duration.short, 36})<{ alert: boolean }>(({ theme, alert }) => ({
37 easing: theme.transitions.easing.easeInOut, 37 padding: 6,
38 }, 38 color: getAlertColor(theme, alert),
39 ), 39 // Clicking on the security label should focus the text field instead.
40 pointerEvents: 'none',
40})); 41}));
41 42
42export default function UrlAdornment({ 43const SecurityLabelText = styled('span', {
44 name: 'SecurityLabel',
45 slot: 'Text',
46})(({ theme }) => ({
47 marginInlineStart: theme.spacing(1),
48 // Keep the same baseline as the input box text.
49 paddingBottom: 1,
50 fontWeight: theme.typography.fontWeightMedium,
51 userSelect: 'none',
52}));
53
54export default function SecurityLabel({
43 splitResult, 55 splitResult,
44 changed, 56 changed,
57 position,
45}: { 58}: {
46 splitResult: SplitResult; 59 splitResult: SplitResult;
47 changed: boolean; 60 changed: boolean;
61 position: 'start' | 'end';
48}): JSX.Element { 62}): JSX.Element {
49 const { type } = splitResult; 63 const { type } = splitResult;
50 if (changed || type === 'empty') { 64 if (changed || type === 'empty') {
51 return ( 65 return (
52 <IconAdornment position="start"> 66 <SecurityLabelRoot alert={false} position={position} aria-hidden>
53 <IconGlobe fontSize="small" /> 67 <IconGlobe fontSize="small" />
54 </IconAdornment> 68 </SecurityLabelRoot>
55 ); 69 );
56 } 70 }
57 switch (type) { 71 switch (type) {
58 case 'valid': { 72 case 'valid': {
59 const { secure } = splitResult; 73 const { secure } = splitResult;
60 return secure ? ( 74 return secure ? (
61 <ButtonAdornment position="start"> 75 <SecurityLabelRoot
62 <FastColorChangingButton 76 alert={false}
63 aria-label="Show certificate" 77 position={position}
64 color="inherit" 78 aria-label="Secure connection"
65 className={NO_LABEL_BUTTON_CLASS_NAME} 79 >
66 startIcon={<IconHttps />} 80 <IconHttps fontSize="small" />
67 /> 81 </SecurityLabelRoot>
68 </ButtonAdornment>
69 ) : ( 82 ) : (
70 <ButtonAdornment position="start"> 83 <SecurityLabelRoot alert position={position}>
71 <FastColorChangingButton color="error" startIcon={<IconWarning />}> 84 <IconHttp fontSize="small" />
72 Not secure 85 <SecurityLabelText>Not secure</SecurityLabelText>
73 </FastColorChangingButton> 86 </SecurityLabelRoot>
74 </ButtonAdornment>
75 ); 87 );
76 } 88 }
77 case 'invalid': 89 case 'invalid':
78 return ( 90 return (
79 <ButtonAdornment position="start"> 91 <SecurityLabelRoot alert position={position}>
80 <FastColorChangingButton color="error" startIcon={<IconWarning />}> 92 <IconWarning fontSize="small" />
81 Unknown site 93 <SecurityLabelText>Unknown site</SecurityLabelText>
82 </FastColorChangingButton> 94 </SecurityLabelRoot>
83 </ButtonAdornment>
84 ); 95 );
85 default: 96 default:
86 /* eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- 97 /* eslint-disable-next-line @typescript-eslint/restrict-template-expressions --
diff --git a/packages/renderer/src/components/locationBar/UrlOverlay.tsx b/packages/renderer/src/components/locationBar/UrlOverlay.tsx
index f7a3c4c..d590709 100644
--- a/packages/renderer/src/components/locationBar/UrlOverlay.tsx
+++ b/packages/renderer/src/components/locationBar/UrlOverlay.tsx
@@ -21,6 +21,7 @@
21import { styled } from '@mui/material/styles'; 21import { styled } from '@mui/material/styles';
22import React from 'react'; 22import React from 'react';
23 23
24import getAlertColor from './getAlertColor';
24import type { SplitResult } from './splitUrl'; 25import type { SplitResult } from './splitUrl';
25 26
26const PrimaryFragment = styled('span', { 27const PrimaryFragment = styled('span', {
@@ -28,7 +29,7 @@ const PrimaryFragment = styled('span', {
28 slot: 'PrimaryFragment', 29 slot: 'PrimaryFragment',
29 shouldForwardProp: (prop) => prop !== 'alert', 30 shouldForwardProp: (prop) => prop !== 'alert',
30})<{ alert: boolean }>(({ theme, alert }) => ({ 31})<{ alert: boolean }>(({ theme, alert }) => ({
31 color: alert ? theme.palette.error.main : theme.palette.text.primary, 32 color: getAlertColor(theme, alert),
32})); 33}));
33 34
34const SecondaryFragment = styled('span', { 35const SecondaryFragment = styled('span', {
diff --git a/packages/renderer/src/components/locationBar/getAlertColor.ts b/packages/renderer/src/components/locationBar/getAlertColor.ts
new file mode 100644
index 0000000..82b5f55
--- /dev/null
+++ b/packages/renderer/src/components/locationBar/getAlertColor.ts
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import { Theme } from '@mui/material/styles';
22
23export default function getAlertColor({ palette }: Theme, alert: boolean) {
24 if (alert) {
25 return palette.mode === 'dark' ? palette.error.light : palette.error.main;
26 }
27 return palette.text.primary;
28}