Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mobile - Slash inserter #29772

Merged
merged 69 commits into from
May 21, 2021
Merged
Show file tree
Hide file tree
Changes from 65 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
eaf97c3
Crudely fork web implementation to remove invariant violations
mkevins Mar 8, 2021
104ee27
WIP - Better UI for testing. Reset Autocomplete on delete content
Mar 8, 2021
e8e4111
Use a synthetic event to bind onEnter to the autocompletion
mkevins Mar 9, 2021
85f8531
Mobile - Move onEnter logic to native Rich Text
Mar 9, 2021
93e7e41
Simplify event conformance in native RichText
mkevins Mar 10, 2021
685de72
Remove native variant of block-editor autocomplete
mkevins Mar 10, 2021
3954b50
Use Platform variant to wrap text on native, leaving web unchanged
mkevins Mar 10, 2021
3f70559
Extract autocomplete functions
mkevins Mar 10, 2021
e9b4e31
Merge autocomplete variants, and create an autocomplete ui variant
mkevins Mar 10, 2021
2fc7319
WIP - add Popover library and begin experimenting
mkevins Mar 10, 2021
0f0654e
Move optional from this to function
mkevins Mar 10, 2021
ee0e863
WIP - Popover changes
Mar 10, 2021
e420d99
Extract default useItems hook from autocomplete ui
mkevins Mar 10, 2021
8521451
Rename extracted ui for consistency
mkevins Mar 10, 2021
c4fd28b
Remove Popover library. Add UI for the slash inserter selector
Mar 11, 2021
ea1a65c
Remove lodash usage
Mar 11, 2021
3977c7a
Fix preventDefault on Android
Mar 11, 2021
9c8ca3c
Simplify customEditableOnKeyDown stubs
mkevins Mar 12, 2021
6d85b4e
Rename autocompletion slot fill and move to mobile components
mkevins Mar 12, 2021
b10e145
Reset scroll position when autocomplete items change
mkevins Mar 12, 2021
757e14f
Adjust styles for BlurView
mkevins Mar 12, 2021
74bae14
Merge branch 'trunk' into rnmobile/feature/slash-inserter
mkevins Mar 12, 2021
a69732d
Update autocompletion item container view styles for Android
mkevins Mar 12, 2021
3e08dc7
Update autocomplete styles
Mar 12, 2021
7e12d8a
Merge branch 'trunk' into rnmobile/feature/slash-inserter
Mar 15, 2021
6344e5a
Fix order of imports
Mar 15, 2021
528a83f
Put feature behind __DEV__ flag
mkevins Mar 25, 2021
311ea6d
Merge branch 'trunk' into rnmobile/feature/slash-inserter
mkevins Mar 26, 2021
6a2e058
Remove mobile wrapper since it no longer uses the label attribute to …
Mar 26, 2021
491cd4e
Add missing line break
Mar 26, 2021
5bf1858
Update active item styles
Mar 26, 2021
1bafe1d
Revert "Put feature behind __DEV__ flag"
Mar 31, 2021
de73564
Merge branch 'trunk' into rnmobile/feature/slash-inserter
Mar 31, 2021
b545556
Merge branch 'trunk' into rnmobile/feature/slash-inserter
mkevins Apr 1, 2021
e2e6761
Add slash-inserter e2e test
mkevins Apr 1, 2021
9e559c8
Update light-mode active background color for slash complete option
mkevins Apr 2, 2021
8f3b0e0
Update placeholder text to hint the slash inserter
Apr 6, 2021
2e6a942
Slash inserter animation and active item color update
Apr 6, 2021
8139ddd
Styles cleanup
Apr 6, 2021
f669fd0
Pass isVisible to useCallback
Apr 6, 2021
9adc7f7
Adjust autocompleter animation timing
mkevins Apr 7, 2021
4d184ac
Remove redundant text decoration
mkevins Apr 7, 2021
58a2b12
Adjust colors
mkevins Apr 7, 2021
7f802a8
Use shorter writing prompt
mkevins Apr 7, 2021
7f3718b
Make test description more specific
mkevins Apr 7, 2021
4dfdfee
Styles update
Apr 7, 2021
cf42b0e
Merge branch 'trunk' into rnmobile/feature/slash-inserter
Apr 12, 2021
4666289
Merge branch 'trunk' into rnmobile/feature/slash-inserter
Apr 12, 2021
653ad2f
Mobile: Update default text placeholder, fix autocompleter position i…
Apr 27, 2021
7d7a1dc
Merge branch 'trunk' into rnmobile/feature/slash-inserter
Apr 27, 2021
c251037
Use I with serif for italic format library icon
mkevins Apr 30, 2021
1d94858
Mobile - Add Slash inserter e2e tests
Apr 30, 2021
b2ae967
Merge branch 'rnmobile/feature/slash-inserter' of github.com:WordPres…
Apr 30, 2021
b22fca1
Merge with trunk
Apr 30, 2021
f2f2a9c
Unify e2e files
Apr 30, 2021
183d194
Revert placeholders change
Apr 30, 2021
756c056
Mark AutocompletionItemsSlot and AutocompletionItemsFill as __unstable
May 5, 2021
47bd27e
Update styles to BEM naming
May 5, 2021
167f93e
Merge branch 'trunk' into rnmobile/feature/slash-inserter
May 12, 2021
8157152
Revert "Use I with serif for italic format library icon"
May 12, 2021
2df7530
Fix slash inserter e2e
May 13, 2021
a7eb093
Fix e2e test on Android
May 14, 2021
7808070
Extract slash inserter assertion into separate function
mkevins May 19, 2021
850d1f9
Extract platform variants for BackgroundView to separate files
mkevins May 19, 2021
d16ca21
Merge branch 'trunk' into rnmobile/feature/slash-inserter
May 19, 2021
99bb059
Merge branch 'trunk' into rnmobile/feature/slash-inserter
May 20, 2021
c598a2f
Merge branch 'trunk' into rnmobile/feature/slash-inserter
May 20, 2021
5847eb4
Merge branch 'trunk' into rnmobile/feature/slash-inserter
May 20, 2021
ed926f8
Merge branch 'trunk' into rnmobile/feature/slash-inserter
May 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/base-styles/_colors.native.scss
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ $gray-lighten-10: lighten($gray, 10%); // #a8bece
$gray-lighten-20: lighten($gray, 20%); // #c8d7e1
$gray-lighten-30: lighten($gray, 30%); // #e9eff3
$gray-darken-20: darken($gray, 20%); // #4f748e
$gray-darken-30: darken($gray, 30%); // #3d596d

// Custom
$toolbar-button: #7b9ab1;
Expand Down

This file was deleted.

86 changes: 86 additions & 0 deletions packages/components/src/autocomplete/autocompleter-ui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* External dependencies
*/
import classnames from 'classnames';
import { map } from 'lodash';

/**
* WordPress dependencies
*/
import { useLayoutEffect } from '@wordpress/element';
import { useAnchorRef } from '@wordpress/rich-text';

/**
* Internal dependencies
*/
import getDefaultUseItems from './get-default-use-items';
import Button from '../button';
import Popover from '../popover';

export function getAutoCompleterUI( autocompleter ) {
const useItems = autocompleter.useItems
? autocompleter.useItems
: getDefaultUseItems( autocompleter );

function AutocompleterUI( {
filterValue,
instanceId,
listBoxId,
className,
selectedIndex,
onChangeOptions,
onSelect,
onReset,
value,
contentRef,
} ) {
const [ items ] = useItems( filterValue );
const anchorRef = useAnchorRef( { ref: contentRef, value } );

useLayoutEffect( () => {
onChangeOptions( items );
}, [ items ] );

if ( ! items.length > 0 ) {
return null;
}

return (
<Popover
focusOnMount={ false }
onClose={ onReset }
position="top right"
className="components-autocomplete__popover"
anchorRef={ anchorRef }
>
<div
id={ listBoxId }
role="listbox"
className="components-autocomplete__results"
>
{ map( items, ( option, index ) => (
<Button
key={ option.key }
id={ `components-autocomplete-item-${ instanceId }-${ option.key }` }
role="option"
aria-selected={ index === selectedIndex }
disabled={ option.isDisabled }
className={ classnames(
'components-autocomplete__result',
className,
{
'is-selected': index === selectedIndex,
}
) }
onClick={ () => onSelect( option ) }
>
{ option.label }
</Button>
) ) }
</div>
</Popover>
);
}

return AutocompleterUI;
}
213 changes: 213 additions & 0 deletions packages/components/src/autocomplete/autocompleter-ui.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
/**
* External dependencies
*/
import {
View,
Animated,
StyleSheet,
Text,
TouchableOpacity,
ScrollView,
} from 'react-native';

/**
* WordPress dependencies
*/
import {
useLayoutEffect,
useEffect,
useRef,
useState,
useCallback,
} from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import {
Icon,
__unstableAutocompletionItemsFill as AutocompletionItemsFill,
} from '@wordpress/components';
import { usePreferredColorSchemeStyle } from '@wordpress/compose';

/**
* Internal dependencies
*/
import BackgroundView from './background-view';
import getDefaultUseItems from './get-default-use-items';
import styles from './style.scss';

const { compose: stylesCompose } = StyleSheet;

export function getAutoCompleterUI( autocompleter ) {
const useItems = autocompleter.useItems
? autocompleter.useItems
: getDefaultUseItems( autocompleter );

function AutocompleterUI( {
filterValue,
selectedIndex,
onChangeOptions,
onSelect,
value,
reset,
} ) {
const [ items ] = useItems( filterValue );
const scrollViewRef = useRef();
const animationValue = useRef( new Animated.Value( 0 ) ).current;
const [ isVisible, setIsVisible ] = useState( false );
const { text } = value;

useEffect( () => {
if ( ! isVisible && text.length > 0 ) {
setIsVisible( true );
}
}, [ isVisible, text ] );

useLayoutEffect( () => {
onChangeOptions( items );
scrollViewRef.current?.scrollTo( { x: 0, animated: false } );

if ( isVisible && text.length > 0 ) {
startAnimation( true );
} else if ( isVisible && text.length === 0 ) {
startAnimation( false );
}
}, [ items, isVisible, text ] );

const activeItemStyles = usePreferredColorSchemeStyle(
styles[ 'components-autocomplete__item-active' ],
styles[ 'components-autocomplete__item-active-dark' ]
);

const iconStyles = usePreferredColorSchemeStyle(
styles[ 'components-autocomplete__icon' ],
styles[ 'components-autocomplete__icon-active-dark' ]
);

const activeIconStyles = usePreferredColorSchemeStyle(
styles[ 'components-autocomplete__icon-active ' ],
styles[ 'components-autocomplete__icon-active-dark' ]
);

const textStyles = usePreferredColorSchemeStyle(
styles[ 'components-autocomplete__text' ],
styles[ 'components-autocomplete__text-dark' ]
);

const activeTextStyles = usePreferredColorSchemeStyle(
styles[ 'components-autocomplete__text-active' ],
styles[ 'components-autocomplete__text-active-dark' ]
);

const startAnimation = useCallback(
( show ) => {
Animated.timing( animationValue, {
toValue: show ? 1 : 0,
duration: show ? 200 : 100,
useNativeDriver: true,
} ).start( ( { finished } ) => {
if ( finished && ! show && isVisible ) {
setIsVisible( false );
reset();
}
} );
},
[ isVisible ]
);

const contentStyles = {
transform: [
{
translateY: animationValue.interpolate( {
inputRange: [ 0, 1 ],
outputRange: [
styles[ 'components-autocomplete' ].height,
0,
],
} ),
},
],
};

if ( ! items.length > 0 || ! isVisible ) {
return null;
}

return (
<AutocompletionItemsFill>
<View style={ styles[ 'components-autocomplete' ] }>
<Animated.View style={ contentStyles }>
<BackgroundView>
<ScrollView
ref={ scrollViewRef }
horizontal
contentContainerStyle={
styles[ 'components-autocomplete__content' ]
}
showsHorizontalScrollIndicator={ false }
keyboardShouldPersistTaps="always"
accessibilityLabel={
// translators: Slash inserter autocomplete results
__( 'Slash inserter results' )
}
>
{ items.map( ( option, index ) => {
const isActive = index === selectedIndex;
const itemStyle = stylesCompose(
styles[
'components-autocomplete__item'
],
isActive && activeItemStyles
);
const textStyle = stylesCompose(
textStyles,
isActive && activeTextStyles
);
const iconStyle = stylesCompose(
iconStyles,
isActive && activeIconStyles
);

return (
<TouchableOpacity
activeOpacity={ 0.5 }
style={ itemStyle }
key={ index }
onPress={ () => onSelect( option ) }
accessibilityLabel={ sprintf(
// translators: %s: Block name e.g. "Image block"
__( '%s block' ),
option?.value?.title
) }
>
<View
style={
styles[
'components-autocomplete__icon'
]
}
>
<Icon
icon={
option?.value?.icon?.src
}
size={ 24 }
style={ iconStyle }
/>
</View>
<Text style={ textStyle }>
{ option?.value?.title }
</Text>
</TouchableOpacity>
);
} ) }
</ScrollView>
</BackgroundView>
</Animated.View>
</View>
</AutocompletionItemsFill>
);
}

return AutocompleterUI;
}

export default getAutoCompleterUI;
25 changes: 25 additions & 0 deletions packages/components/src/autocomplete/background-view.android.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* External dependencies
*/
import { View } from 'react-native';

/**
* WordPress dependencies
*/
import { usePreferredColorSchemeStyle } from '@wordpress/compose';

/**
* Internal dependencies
*/
import styles from './style.scss';

const BackgroundView = ( { children } ) => {
const backgroundStyles = usePreferredColorSchemeStyle(
styles[ 'components-autocomplete__background' ],
styles[ 'components-autocomplete__background-dark' ]
);

return <View style={ backgroundStyles }>{ children }</View>;
};

export default BackgroundView;
23 changes: 23 additions & 0 deletions packages/components/src/autocomplete/background-view.ios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* External dependencies
*/
import { BlurView } from '@react-native-community/blur';

/**
* Internal dependencies
*/
import styles from './style.scss';

const BackgroundView = ( { children } ) => {
return (
<BlurView
style={ styles[ 'components-autocomplete__background-blur' ] }
blurType="prominent"
blurAmount={ 10 }
>
{ children }
</BlurView>
);
};

export default BackgroundView;
Loading