diff --git a/.eslintignore b/.eslintignore index 3f9c753e3..3bfe95b0b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -510,13 +510,13 @@ packages/app-mobile/commands/util/goToNote.js packages/app-mobile/components/ActionButton.js packages/app-mobile/components/BackButtonDialogBox.js packages/app-mobile/components/CameraView.js -packages/app-mobile/components/CustomButton.js packages/app-mobile/components/DismissibleDialog.js packages/app-mobile/components/Dropdown.test.js packages/app-mobile/components/Dropdown.js packages/app-mobile/components/ExtendedWebView.js packages/app-mobile/components/FolderPicker.js packages/app-mobile/components/Icon.js +packages/app-mobile/components/IconButton.js packages/app-mobile/components/Modal.js packages/app-mobile/components/ModalDialog.js packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js diff --git a/.gitignore b/.gitignore index a173867be..187a395b4 100644 --- a/.gitignore +++ b/.gitignore @@ -489,13 +489,13 @@ packages/app-mobile/commands/util/goToNote.js packages/app-mobile/components/ActionButton.js packages/app-mobile/components/BackButtonDialogBox.js packages/app-mobile/components/CameraView.js -packages/app-mobile/components/CustomButton.js packages/app-mobile/components/DismissibleDialog.js packages/app-mobile/components/Dropdown.test.js packages/app-mobile/components/Dropdown.js packages/app-mobile/components/ExtendedWebView.js packages/app-mobile/components/FolderPicker.js packages/app-mobile/components/Icon.js +packages/app-mobile/components/IconButton.js packages/app-mobile/components/Modal.js packages/app-mobile/components/ModalDialog.js packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js diff --git a/packages/app-mobile/components/Icon.tsx b/packages/app-mobile/components/Icon.tsx index a074623e4..1f9ca927b 100644 --- a/packages/app-mobile/components/Icon.tsx +++ b/packages/app-mobile/components/Icon.tsx @@ -4,8 +4,8 @@ import { TextStyle, Text } from 'react-native'; const FontAwesomeIcon = require('react-native-vector-icons/FontAwesome5').default; const AntIcon = require('react-native-vector-icons/AntDesign').default; -const MaterialIcon = require('react-native-vector-icons/MaterialIcons').default; - +const MaterialCommunityIcon = require('react-native-vector-icons/MaterialCommunityIcons').default; +const Ionicon = require('react-native-vector-icons/Ionicons').default; interface Props { name: string; @@ -53,7 +53,9 @@ const Icon: React.FC = props => { } else if (namePrefix === 'ant') { return ; } else if (namePrefix === 'material') { - return ; + return ; + } else if (namePrefix === 'ionicon') { + return ; } else if (namePrefix === 'text') { return ( void; interface ButtonProps { onPress: ButtonClickListener; // Accessibility label and text shown in a tooltip - description?: string; + description: string; - children: ReactNode; + iconName: string; + iconStyle: TextStyle; themeId: number; - style?: ViewStyle; - pressedStyle?: ViewStyle; - contentStyle?: ViewStyle; + containerStyle?: ViewStyle; + contentWrapperStyle?: ViewStyle; // Additional accessibility information. See View.accessibilityHint accessibilityHint?: string; @@ -35,7 +35,7 @@ interface ButtonProps { disabled?: boolean; } -const CustomButton = (props: ButtonProps) => { +const IconButton = (props: ButtonProps) => { const [tooltipVisible, setTooltipVisible] = useState(false); const [buttonLayout, setButtonLayout] = useState(null); const tooltipStyles = useTooltipStyles(props.themeId); @@ -67,19 +67,6 @@ const CustomButton = (props: ButtonProps) => { setTooltipVisible(true); }, []); - // Select different user-specified styles if selected/unselected. - const onStyleChange = useCallback((state: PressableStateCallbackType): StyleProp => { - let result = { ...props.style }; - - if (state.pressed) { - result = { - ...result, - ...props.pressedStyle, - }; - } - return result; - }, [props.pressedStyle, props.style]); - const onButtonLayout = useCallback((event: LayoutChangeEvent) => { const layoutEvt = event.nativeEvent.layout; @@ -87,7 +74,6 @@ const CustomButton = (props: ButtonProps) => { setButtonLayout({ ...layoutEvt }); }, []); - const button = ( { onPressIn={onPressIn} onPressOut={onPressOut} - style={ onStyleChange } + style={ props.containerStyle } disabled={ props.disabled ?? false } onLayout={ onButtonLayout } @@ -107,62 +93,70 @@ const CustomButton = (props: ButtonProps) => { > - { props.children } + ); - const tooltip = ( - { + if (!props.description) return null; - // Position the menu beneath the button so the tooltip appears in the - // correct location. - style={{ - left: buttonLayout?.x, - top: buttonLayout?.y, - position: 'absolute', - zIndex: -1, - }} - > - - - - - {props.description} - - - - - ); + return ( + + + + + + {props.description} + + + + + ); + }; return ( <> - {props.description ? tooltip : null} + {renderTooltip()} {button} ); @@ -187,4 +181,4 @@ const useTooltipStyles = (themeId: number) => { }, [themeId]); }; -export default CustomButton; +export default IconButton; diff --git a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.tsx b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.tsx index b528dbb34..4f7b6afba 100644 --- a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.tsx +++ b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.tsx @@ -14,7 +14,7 @@ interface ToggleOverflowButtonProps { // Button that shows/hides the overflow menu. const ToggleOverflowButton: React.FC = (props: ToggleOverflowButtonProps) => { const spec: ButtonSpec = { - icon: 'material more-horiz', + icon: 'material dots-horizontal', description: props.overflowVisible ? _('Hide more actions') : _('Show more actions'), active: props.overflowVisible, diff --git a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.tsx b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.tsx index e1f316fd4..7a486a241 100644 --- a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.tsx +++ b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.tsx @@ -14,9 +14,7 @@ import { Theme } from '@joplin/lib/themes/type'; import * as React from 'react'; import { ReactNode, useCallback, useState, useEffect } from 'react'; import { View, ViewStyle } from 'react-native'; -import CustomButton from '../../CustomButton'; - -const AntIcon = require('react-native-vector-icons/AntDesign').default; +import IconButton from '../../IconButton'; interface Props { children: ReactNode; @@ -54,10 +52,10 @@ const ToggleSpaceButton = (props: Props) => { height: additionalPositiveSpace, zIndex: -2, }} /> - { alignItems: 'center', }} onPress={onDecreaseSpace} - > - - + + iconName='material chevron-down' + iconStyle={{ color: theme.color }} + /> ); diff --git a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.tsx b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.tsx index 17272890b..3ec396d25 100644 --- a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.tsx +++ b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.tsx @@ -2,8 +2,7 @@ import * as React from 'react'; import { useCallback, useMemo } from 'react'; import { TextStyle, StyleSheet } from 'react-native'; import { ButtonSpec, StyleSheetData } from './types'; -import CustomButton from '../../CustomButton'; -import Icon from '../../Icon'; +import IconButton from '../../IconButton'; export const buttonSize = 54; @@ -58,16 +57,16 @@ const ToolbarButton = ({ styleSheet, spec, onActionComplete, style }: ToolbarBut }, [disabled, sourceOnPress, onActionComplete]); return ( - - - + + iconName={spec.icon} + iconStyle={styles.iconStyle} + /> ); }; diff --git a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useActionButtons.ts b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useActionButtons.ts index 47d7afaa5..330c62434 100644 --- a/packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useActionButtons.ts +++ b/packages/app-mobile/components/NoteEditor/MarkdownToolbar/buttons/useActionButtons.ts @@ -51,7 +51,7 @@ const useActionButtons = (props: ActionButtonRowProps) => { }); actionButtons.push({ - icon: 'material search', + icon: 'material magnify', description: ( props.searchState.dialogVisible ? _('Close') : _('Find and replace') ), @@ -63,7 +63,7 @@ const useActionButtons = (props: ActionButtonRowProps) => { }); actionButtons.push({ - icon: 'material keyboard-hide', + icon: 'material keyboard-close', description: _('Hide keyboard'), disabled: !props.keyboardVisible, visible: props.hasSoftwareKeyboard && Platform.OS === 'ios', diff --git a/packages/app-mobile/components/NoteEditor/SearchPanel.tsx b/packages/app-mobile/components/NoteEditor/SearchPanel.tsx index ddbb9bf21..e6b4a22b9 100644 --- a/packages/app-mobile/components/NoteEditor/SearchPanel.tsx +++ b/packages/app-mobile/components/NoteEditor/SearchPanel.tsx @@ -2,13 +2,12 @@ const React = require('react'); const { useMemo, useState, useEffect } = require('react'); -const MaterialCommunityIcon = require('react-native-vector-icons/MaterialCommunityIcons').default; import { EditorSettings } from './types'; import { _ } from '@joplin/lib/locale'; import { BackHandler, TextInput, View, Text, StyleSheet, ViewStyle } from 'react-native'; import { Theme } from '@joplin/lib/themes/type'; -import CustomButton from '../CustomButton'; +import IconButton from '../IconButton'; import { SearchState } from '@joplin/editor/types'; import { SearchControl } from './types'; @@ -43,14 +42,14 @@ interface ActionButtonProps { const ActionButton = (props: ActionButtonProps) => { return ( - - - + iconName={`material ${props.iconName}`} + iconStyle={props.styles.buttonText} + /> ); }; @@ -68,9 +67,9 @@ const ToggleButton = (props: ToggleButtonProps) => { const active = props.active; return ( - { }} description={props.title} accessibilityRole='switch' - > - - + } + /> ); }; diff --git a/packages/app-mobile/components/ScreenHeader/index.tsx b/packages/app-mobile/components/ScreenHeader/index.tsx index b6132d001..78ac67dc9 100644 --- a/packages/app-mobile/components/ScreenHeader/index.tsx +++ b/packages/app-mobile/components/ScreenHeader/index.tsx @@ -15,7 +15,7 @@ const { dialogs } = require('../../utils/dialogs.js'); const DialogBox = require('react-native-dialogbox').default; import { FolderEntity } from '@joplin/lib/services/database/types'; import { State } from '@joplin/lib/reducer'; -import CustomButton from '../CustomButton'; +import IconButton from '../IconButton'; import FolderPicker from '../FolderPicker'; import { itemIsInTrash } from '@joplin/lib/services/trash'; import restoreItems from '@joplin/lib/services/trash/restoreItems'; @@ -363,26 +363,25 @@ class ScreenHeaderComponent extends PureComponent { if (!options.visible) return null; - const icon = ; const viewStyle = options.disabled ? this.styles().iconButtonDisabled : this.styles().iconButton; return ( - - {icon} - + iconName={options.iconName} + iconStyle={this.styles().topIcon} + /> ); }; const renderUndoButton = () => { return renderTopButton({ - iconName: 'arrow-undo-circle-sharp', + iconName: 'ionicon arrow-undo-circle-sharp', description: _('Undo'), onPress: this.props.onUndoButtonPress, visible: this.props.showUndoButton, @@ -392,7 +391,7 @@ class ScreenHeaderComponent extends PureComponent { return renderTopButton({ - iconName: 'arrow-redo-circle-sharp', + iconName: 'ionicon arrow-redo-circle-sharp', description: _('Redo'), onPress: this.props.onRedoButtonPress, visible: this.props.showRedoButton, @@ -402,30 +401,32 @@ class ScreenHeaderComponent extends PureComponent - - + contentWrapperStyle={styles.iconButton} + + iconName="ionicon checkmark-circle-outline" + iconStyle={styles.topIcon} + /> ); } // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied function searchButton(styles: any, onPress: OnPressCallback) { return ( - - - + contentWrapperStyle={styles.iconButton} + + iconName='ionicon search' + iconStyle={styles.topIcon} + /> ); } @@ -438,21 +439,22 @@ class ScreenHeaderComponent extends PureComponent - - + contentWrapperStyle={styles.iconButton} + + iconName="ionicon extension-puzzle" + iconStyle={styles.topIcon} + /> ); }; // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied function deleteButton(styles: any, onPress: OnPressCallback, disabled: boolean) { return ( - - - + contentWrapperStyle={disabled ? styles.iconButtonDisabled : styles.iconButton} + + iconName='ionicon trash' + iconStyle={styles.topIcon} + /> ); } // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied function restoreButton(styles: any, onPress: OnPressCallback, disabled: boolean) { return ( - - - + contentWrapperStyle={disabled ? styles.iconButtonDisabled : styles.iconButton} + + iconName='ionicon reload-circle' + iconStyle={styles.topIcon} + /> ); } // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied function duplicateButton(styles: any, onPress: OnPressCallback, disabled: boolean) { return ( - - - + contentWrapperStyle={disabled ? styles.iconButtonDisabled : styles.iconButton} + iconName='ionicon copy' + iconStyle={styles.topIcon} + /> ); } diff --git a/packages/tools/cspell/dictionary4.txt b/packages/tools/cspell/dictionary4.txt index 33ee97b06..933b559e5 100644 --- a/packages/tools/cspell/dictionary4.txt +++ b/packages/tools/cspell/dictionary4.txt @@ -108,3 +108,4 @@ libasound libatk ENOTFOUND Scaleway +Ionicon