Skip to content

Commit 62aba30

Browse files
larkoxCopilot
andauthored
Add several UX fixes to set command screen on playbooks (#9136)
* Add several UX fixes to set command screen on playbooks * Update app/products/playbooks/screens/edit_command/edit_command.test.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update app/components/autocomplete/autocomplete.test.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix keyboard overlap --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent a4e495a commit 62aba30

File tree

6 files changed

+62
-20
lines changed

6 files changed

+62
-20
lines changed

app/components/autocomplete/autocomplete.test.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,36 @@ describe('Autocomplete', () => {
120120
expect(getByTestId('slash-suggestion-mock')).toBeTruthy();
121121
expect(getByTestId('app-slash-suggestion-mock')).toBeTruthy();
122122
});
123+
124+
it('should render with the correct horizontal padding', () => {
125+
const props = getBaseProps();
126+
const {getByTestId, rerender} = render(<Autocomplete {...props}/>);
127+
128+
// Default horizontal padding is 8
129+
expect(getByTestId('autocomplete')).toHaveStyle({left: 8, right: 8});
130+
131+
// Set horizontal padding to 20
132+
props.horizontalPadding = 20;
133+
rerender(<Autocomplete {...props}/>);
134+
135+
expect(getByTestId('autocomplete')).toHaveStyle({left: 20, right: 20});
136+
});
137+
138+
it('should set the correct max height by default', () => {
139+
const props = getBaseProps();
140+
props.availableSpace = {value: 1000} as SharedValue<number>;
141+
const {getByTestId} = render(<Autocomplete {...props}/>);
142+
143+
// Default max height is 230
144+
expect(getByTestId('autocomplete')).toHaveStyle({maxHeight: 230});
145+
});
146+
147+
it('should set the correct max height when useAllAvailableSpace is true', () => {
148+
const props = getBaseProps();
149+
props.availableSpace = {value: 1000} as SharedValue<number>;
150+
props.useAllAvailableSpace = true;
151+
const {getByTestId} = render(<Autocomplete {...props}/>);
152+
153+
expect(getByTestId('autocomplete')).toHaveStyle({maxHeight: 1000});
154+
});
123155
});

app/components/autocomplete/autocomplete.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ import AppSlashSuggestion from './slash_suggestion/app_slash_suggestion/';
1919
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
2020
return {
2121
base: {
22-
left: 8,
23-
right: 8,
2422
position: 'absolute',
2523
},
2624
borders: {
@@ -65,6 +63,8 @@ type Props = {
6563
teamId?: string;
6664
containerStyle?: StyleProp<ViewStyle>;
6765
autocompleteProviders?: AutocompleteProviders;
66+
useAllAvailableSpace?: boolean;
67+
horizontalPadding?: number;
6868
}
6969

7070
type AutocompleteProviders = {
@@ -99,6 +99,8 @@ const Autocomplete = ({
9999
containerStyle,
100100
teamId,
101101
autocompleteProviders = defaultAutocompleteProviders,
102+
useAllAvailableSpace = false,
103+
horizontalPadding = 8,
102104
}: Props) => {
103105
const theme = useTheme();
104106
const isTablet = useIsTablet();
@@ -121,8 +123,8 @@ const Autocomplete = ({
121123
const maxHeightAdjust = (isTablet && isLandscape) ? MAX_LIST_TABLET_DIFF : 0;
122124
const defaultMaxHeight = MAX_LIST_HEIGHT - maxHeightAdjust;
123125
const maxHeight = useDerivedValue(() => {
124-
return Math.min(availableSpace.value, defaultMaxHeight);
125-
}, [defaultMaxHeight]);
126+
return useAllAvailableSpace ? availableSpace.value : Math.min(availableSpace.value, defaultMaxHeight);
127+
}, [defaultMaxHeight, useAllAvailableSpace, availableSpace]);
126128

127129
const containerAnimatedStyle = useAnimatedStyle(() => {
128130
return growDown ?
@@ -131,7 +133,7 @@ const Autocomplete = ({
131133
}, [growDown, position]);
132134

133135
const containerStyles = useMemo(() => {
134-
const s: StyleProp<ViewStyle> = [style.base, containerAnimatedStyle];
136+
const s: StyleProp<ViewStyle> = [style.base, {left: horizontalPadding, right: horizontalPadding}, containerAnimatedStyle];
135137
if (hasElements) {
136138
s.push(style.borders);
137139
}
@@ -142,7 +144,7 @@ const Autocomplete = ({
142144
s.push(containerStyle);
143145
}
144146
return s;
145-
}, [hasElements, style, containerStyle, containerAnimatedStyle]);
147+
}, [style.base, style.borders, style.shadow, horizontalPadding, containerAnimatedStyle, hasElements, containerStyle]);
146148

147149
return (
148150
<Animated.View

app/products/playbooks/screens/edit_command/edit_command.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ describe('EditCommand', () => {
5858
expect(editCommandForm.props.channelId).toBe(props.channelId);
5959
});
6060

61-
it('renders correctly without saved command', () => {
61+
it('renders correctly without saved command, adding a slash automatically', () => {
6262
const props = getBaseProps();
6363
props.savedCommand = undefined;
6464
const {getByTestId} = renderWithEverything(<EditCommand {...props}/>, {database});
6565

6666
const editCommandForm = getByTestId('edit-command-form');
67-
expect(editCommandForm.props.command).toBe('');
67+
expect(editCommandForm.props.command).toBe('/');
6868
});
6969

7070
it('sets up navigation buttons correctly', () => {

app/products/playbooks/screens/edit_command/edit_command.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const CreateOrEditChannel = ({
4646
const theme = useTheme();
4747

4848
const [canSave, setCanSave] = useState(false);
49-
const [command, setCommand] = useState<string>(savedCommand || '');
49+
const [command, setCommand] = useState<string>(savedCommand || '/');
5050

5151
const rightButton = useMemo(() => {
5252
const base = buildNavigationButton(

app/products/playbooks/screens/edit_command/edit_command_form.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ describe('EditCommandForm', () => {
6363
expect(floatingTextInput).toHaveProp('showErrorIcon', false);
6464
expect(floatingTextInput).toHaveProp('spellCheck', false);
6565
expect(floatingTextInput).toHaveProp('disableFullscreenUI', true);
66+
expect(floatingTextInput).toHaveProp('autoFocus', true);
6667

6768
const autocomplete = getByTestId('autocomplete');
6869
expect(autocomplete).toBeTruthy();
@@ -78,6 +79,8 @@ describe('EditCommandForm', () => {
7879
emoji: false,
7980
slash: true,
8081
});
82+
expect(autocomplete).toHaveProp('useAllAvailableSpace', true);
83+
expect(autocomplete).toHaveProp('horizontalPadding', 20);
8184
});
8285

8386
it('calls onCommandChange when text input changes', () => {

app/products/playbooks/screens/edit_command/edit_command_form.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
22
// See LICENSE.txt for license information.
33

4-
import React, {useState, useCallback} from 'react';
4+
import React, {useState, useCallback, useRef} from 'react';
55
import {useIntl} from 'react-intl';
66
import {
77
type LayoutChangeEvent,
88
View,
9-
Platform,
109
StyleSheet,
1110
} from 'react-native';
1211
import {SafeAreaView, type Edges} from 'react-native-safe-area-context';
@@ -15,13 +14,13 @@ import Autocomplete from '@components/autocomplete';
1514
import FloatingTextInput from '@components/floating_text_input_label';
1615
import {useTheme} from '@context/theme';
1716
import {useAutocompleteDefaultAnimatedValues} from '@hooks/autocomplete';
17+
import {useKeyboardOverlap} from '@hooks/device';
1818
import {
1919
getKeyboardAppearanceFromTheme,
2020
} from '@utils/theme';
2121

22-
const BOTTOM_AUTOCOMPLETE_SEPARATION = Platform.select({ios: 10, default: 10});
22+
const BOTTOM_AUTOCOMPLETE_SEPARATION = 4;
2323
const LIST_PADDING = 32;
24-
const AUTOCOMPLETE_ADJUST = 5;
2524

2625
const styles = StyleSheet.create({
2726
container: {
@@ -60,6 +59,9 @@ export default function EditCommandForm({
6059

6160
const [commandFieldHeight, setCommandFieldHeight] = useState(0);
6261

62+
const mainView = useRef<View>(null);
63+
const keyboardOverlap = useKeyboardOverlap(mainView, wrapperHeight);
64+
6365
const labelCommand = formatMessage({id: 'playbooks.edit_command.label', defaultMessage: 'Command'});
6466
const placeholderCommand = formatMessage({id: 'playbooks.edit_command.placeholder', defaultMessage: 'Type a command here'});
6567

@@ -70,14 +72,13 @@ export default function EditCommandForm({
7072
setWrapperHeight(e.nativeEvent.layout.height);
7173
}, []);
7274

73-
const spaceOnTop = LIST_PADDING - AUTOCOMPLETE_ADJUST;
74-
const spaceOnBottom = (wrapperHeight) - (LIST_PADDING + commandFieldHeight + BOTTOM_AUTOCOMPLETE_SEPARATION);
75+
const workingSpace = wrapperHeight - keyboardOverlap;
76+
const spaceOnBottom = (workingSpace) - (LIST_PADDING + commandFieldHeight + (BOTTOM_AUTOCOMPLETE_SEPARATION * 2));
7577

76-
const bottomPosition = (LIST_PADDING + commandFieldHeight);
77-
const topPosition = (wrapperHeight + AUTOCOMPLETE_ADJUST) - LIST_PADDING;
78-
const autocompletePosition = spaceOnBottom > spaceOnTop ? bottomPosition : topPosition;
79-
const autocompleteAvailableSpace = spaceOnBottom > spaceOnTop ? spaceOnBottom : spaceOnTop;
80-
const growDown = spaceOnBottom > spaceOnTop;
78+
const bottomPosition = (LIST_PADDING + commandFieldHeight + BOTTOM_AUTOCOMPLETE_SEPARATION);
79+
const autocompletePosition = bottomPosition;
80+
const autocompleteAvailableSpace = spaceOnBottom;
81+
const growDown = true;
8182

8283
const [animatedAutocompletePosition, animatedAutocompleteAvailableSpace] = useAutocompleteDefaultAnimatedValues(autocompletePosition, autocompleteAvailableSpace);
8384

@@ -87,6 +88,7 @@ export default function EditCommandForm({
8788
style={styles.container}
8889
testID='playbooks.edit_command.form'
8990
onLayout={onLayoutWrapper}
91+
ref={mainView}
9092
>
9193
<View style={styles.mainView}>
9294
<FloatingTextInput
@@ -103,6 +105,7 @@ export default function EditCommandForm({
103105
value={command}
104106
theme={theme}
105107
onLayout={onLayoutCommand}
108+
autoFocus={true}
106109
/>
107110
</View>
108111
<Autocomplete
@@ -116,6 +119,8 @@ export default function EditCommandForm({
116119
growDown={growDown}
117120
channelId={channelId}
118121
autocompleteProviders={autocompleteProviders}
122+
useAllAvailableSpace={true}
123+
horizontalPadding={20}
119124
/>
120125
</SafeAreaView>
121126
);

0 commit comments

Comments
 (0)