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

Prepare for 2.3.0 release #1902

Merged
merged 2 commits into from
Mar 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
170 changes: 170 additions & 0 deletions docs/versioned_docs/version-2.3.0/api/components/buttons.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
id: buttons
title: Buttons
sidebar_label: Buttons
---

import useBaseUrl from '@docusaurus/useBaseUrl';
import GifGallery from '@site/components/GifGallery';

<GifGallery>
<img src={useBaseUrl('gifs/samplebutton.gif')} width="280" />
</GifGallery>

Gesture handler library provides native components that can act as buttons. These can be treated as a replacement to `TouchableHighlight` or `TouchableOpacity` from RN core. Gesture handler's buttons recognize touches in native which makes the recognition process deterministic, allows for rendering ripples on Android in highly performant way (`TouchableNativeFeedback` requires that touch event does a roundtrip to JS before we can update ripple effect, which makes ripples lag a bit on older phones), and provides native and platform default interaction for buttons that are placed in a scrollable container (in which case the interaction is slightly delayed to prevent button from highlighting when you fling).

Currently Gesture handler library exposes three components that render native touchable elements under the hood:

- `BaseButton`
- `RectButton`
- `BorderlessButton`

On top of that all the buttons are wrapped with `NativeViewGestureHandler` and therefore allow for all the [common gesture handler properties](#common-gesturehandler-properties) and `NativeViewGestureHandler`'s [extra properties](#nativeviewgesturehandler-extra-properties) to be applied to them.

**IMPORTANT**: In order to make buttons accessible, you have to wrap your children in a `View` with `accessible` and `accessibilityRole="button"` props.
Example:

```javascript
// Not accessible:
const NotAccessibleButton = () => (
<RectButton onPress={this._onPress}>
<Text>Foo</Text>
</RectButton>
);
// Accessible:
const AccessibleButton = () => (
<RectButton onPress={this._onPress}>
<View accessible accessibilityRole="button">
<Text>Bar</Text>
</View>
</RectButton>
);
```

It is applicable for both iOS and Android platform. On iOS, you won't be able to even select the button, on Android you won't be able to click it in accessibility mode.

## `BaseButton`

Can be used as a base class if you'd like to implement some custom interaction for when the button is pressed.

Below is a list of properties specific to `BaseButton` component:

### `onActiveStateChange`

function that gets triggered when button changes from inactive to active and vice versa. It passes active state as a boolean variable as a first parameter for that method.

### `onPress`

function that gets triggered when the button gets pressed (analogous to `onPress` in `TouchableHighlight` from RN core).

### `rippleColor` (**Android only**)

defines color of native [ripple](https://developer.android.com/reference/android/graphics/drawable/RippleDrawable) animation used since API level 21.

### `exclusive`

defines if more than one button could be pressed simultaneously. By default set `true`.

## `RectButton`

This type of button component should be used when you deal with rectangular elements or blocks of content that can be pressed, for example table rows or buttons with text and icons. This component provides a platform specific interaction, rendering a rectangular ripple on Android or highlighting the background on iOS and on older versions of Android. In addition to the props of [`BaseButton`](#basebutton-component), it accepts the following:

Below is a list of properties specific to `RectButton` component:

### `underlayColor`

this is the background color that will be dimmed when button is in active state.

### `activeOpacity` (**iOS only**)

opacity applied to the underlay when button is in active state.

## `BorderlessButton`

This type of button component should be used with simple icon-only or text-only buttons. The interaction will be different depending on platform: on Android a borderless ripple will be rendered (it means that the ripple will animate into a circle that can span outside of the view bounds), whereas on iOS the button will be dimmed (similar to how `TouchableOpacity` works). In addition to the props of [`BaseButton`](#basebutton-component), it accepts the following:

Below is a list of properties specific to `BorderlessButton` component:

### `borderless` (**Android only**)

set this to `false` if you want the ripple animation to render only within view bounds.

### `activeOpacity` (**iOS only**)

opacity applied to the button when it is in an active state.

## Design patterns

Components listed here were not designed to behave and look in the same way on both platforms but rather to be used for handling similar behaviour on iOS and Android taking into consideration their's design concepts.

If you wish to get specific information about platforms design patterns, visit [official Apple docs](https://developer.apple.com/design/human-interface-guidelines/ios/controls) and [Material.io guideline](https://material.io/design/components/buttons.html#text-button), which widely describe how to implement coherent design.

This library allows to use native components with native feedback in adequate situations.

If you do not wish to implement custom design approach, `RectButton` and `BorderlessButton` seem to be absolutely enough and there's no need to use anything else. In all the remaining cases you can always rely on `BaseButton` which is a superclass for the other button classes and can be used as a generic `Touchable` replacement that can be customized to your needs.

Below we list some of the common usecases for button components to be used along with the type of button that should be used according to the platform specific design guidelines.

### Lists and action buttons

If you have a list with clickable items or have an action button that need to display as a separate UI block (vs being inlined in a text) you should use `RectButton`. It changes opacity on click and additionally supports a ripple effect on Android.

<GifGallery>
<img src={useBaseUrl('gifs/androidsettings.gif')} width="280" />
<img src={useBaseUrl('gifs/iossettings.gif')} width="280" />
</GifGallery>

To determine emphasis of button it's vital to use fill color or leave it transparent especially on Android.
For medium emphasis you may consider outlined buttons which are used for lower impact than fill buttons.

<GifGallery>
<img src={useBaseUrl('gifs/androidbutton.gif')} width="280" />
</GifGallery>

### Icon or text only buttons

Use `BorderlessButton` for simple icon-only or text-only buttons. The interaction will be different depending on platform: on Android a borderless ripple will be rendered, whereas on iOS the button will be dimmed.
It should be used if you wish to handle non-crucial actions and supportive behaviour.

<GifGallery>
<img src={useBaseUrl('gifs/androidmail.gif')} width="280" />
<img src={useBaseUrl('gifs/iosmail.gif')} width="280" />
</GifGallery>

### `PureNativeButton`

Use a `PureNativeButton` for accessing the native Component used for build more complex buttons listed above.
It's normally is not recommended to use, but it might be useful if we want to wrap it using Animated or Reanimated.

```javascript
import {
createNativeWrapper,
PureNativeButton,
} from 'react-native-gesture-handler';
import Animated from 'react-native-reanimated';
const { event, Value, createAnimatedComponent } = Animated;

const AnimatedRawButton = createNativeWrapper(
createAnimatedComponent(PureNativeButton),
{
shouldCancelWhenOutside: false,
shouldActivateOnStart: false,
}
);

export default class App extends React.Component {
constructor(props) {
super(props);
const state = new Value();
this._onGestureEvent = event([
{
nativeEvent: { state },
},
]);
}

render() {
return <AnimatedRawButton onHandlerStateChange={this._onGestureEvent} />;
}
}
```
147 changes: 147 additions & 0 deletions docs/versioned_docs/version-2.3.0/api/components/drawer-layout.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
id: drawer-layout
title: Drawer Layout
sidebar_label: DrawerLayout
---

import useBaseUrl from '@docusaurus/useBaseUrl';
import GifGallery from '@site/components/GifGallery';

This is a cross-platform replacement for React Native's [DrawerLayoutAndroid](http://facebook.github.io/react-native/docs/drawerlayoutandroid.html) component. It provides a compatible API but allows for the component to be used on both Android and iOS. Please refer to [React Native docs](http://facebook.github.io/react-native/docs/drawerlayoutandroid.html) for the detailed usage for standard parameters.

## Usage:

`DrawerLayout` component isn't exported by default from the `react-native-gesture-handler` package. To use it, import it in the following way:

```js
import DrawerLayout from 'react-native-gesture-handler/DrawerLayout';
```

## Properties:

On top of the standard list of parameters DrawerLayout has an additional set of attributes to customize its behavior. Please refer to the list below:

### `drawerType`

possible values are: `front`, `back` or `slide` (default is `front`). It specifies the way the drawer will be displayed. When set to `front` the drawer will slide in and out along with the gesture and will display on top of the content view. When `back` is used the drawer displays behind the content view and can be revealed with gesture of pulling the content view to the side. Finally `slide` option makes the drawer appear like it is attached to the side of the content view; when you pull both content view and drawer will follow the gesture.

Type `slide`:

<GifGallery>
<img src={useBaseUrl('gifs/drawer-slide.gif')} width="280" />
</GifGallery>

Type `front`:

<GifGallery>
<img src={useBaseUrl('gifs/drawer-front.gif')} width="280" />
</GifGallery>

Type `back`:

<GifGallery>
<img src={useBaseUrl('gifs/drawer-back.gif')} width="280" />
</GifGallery>

### `edgeWidth`

number, allows for defining how far from the edge of the content view the gesture should activate.

### `hideStatusBar`

boolean, when set to `true` Drawer component will use [StatusBar](http://facebook.github.io/react-native/docs/statusbar.html) API to hide the OS status bar whenever the drawer is pulled or when its in an "open" state.

### `statusBarAnimation`

possible values are: `slide`, `none` or `fade` (defaults to `slide`). Can be used when `hideStatusBar` is set to `true` and will select the animation used for hiding/showing the status bar. See [StatusBar](http://facebook.github.io/react-native/docs/statusbar.html#statusbaranimation) documentation for more details.

### `overlayColor`

color (default to `"black"`) of a semi-transparent overlay to be displayed on top of the content view when drawer gets open. A solid color should be used as the opacity is added by the Drawer itself and the opacity of the overlay is animated (from 0% to 70%).

### `renderNavigationView`

function. This attribute is present in the standard implementation already and is one of the required params. Gesture handler version of DrawerLayout make it possible for the function passed as `renderNavigationView` to take an Animated value as a parameter that indicates the progress of drawer opening/closing animation (progress value is 0 when closed and 1 when opened). This can be used by the drawer component to animated its children while the drawer is opening or closing.

### `onDrawerClose`

function. This function is called when the drawer is closed.

### `onDrawerOpen`

function. This function is called when the drawer is opened.

### `onDrawerSlide`

function. This function is called as a drawer sliding open from touch events. The progress of the drawer opening/closing is passed back as 0 when closed and 1 when opened.

### `onDrawerStateChanged`

function. This function is called when the status of the drawer changes. Possible values that can be passed back are: 'Idle', 'Dragging', and 'Settling'.

### `enableTrackpadTwoFingerGesture` (iOS only)

Enables two-finger gestures on supported devices, for example iPads with trackpads. If not enabled the gesture will require click + drag, with enableTrackpadTwoFingerGesture swiping with two fingers will also trigger the gesture.

### `children`

component or function. Children is a component which is rendered by default and is wrapped by drawer. However, it could be also a render function which takes an Animated value as a parameter that indicates the progress of drawer opening/closing animation (progress value is 0 when closed and 1 when opened) is the same way like `renderNavigationView` prop.

## Methods

### `openDrawer(options)`

`openDrawer` can take an optional `options` parameter which is an object, enabling further customization of the open animation.

`options` has two optional properties:

`velocity`: number, the initial velocity of the object attached to the spring. Default 0 (object is at rest).
`speed`: number, controls speed of the animation. Default 12.

### `closeDrawer(options)`

`closeDrawer` can take an optional `options` parameter which is an object, enabling further customization of the close animation.

`options` has two optional properties:

`velocity`: number, the initial velocity of the object attached to the spring. Default 0 (object is at rest).
`speed`: number, controls speed of the animation. Default 12.

## Example:

See the [drawer example](https://github.com/software-mansion/react-native-gesture-handler/blob/main/examples/Example/src/horizontalDrawer/index.tsx) from GestureHandler Example App or view it directly on your phone by visiting [our expo demo](https://snack.expo.io/@adamgrzybowski/react-native-gesture-handler-demo).

```js
class Drawerable extends Component {
handleDrawerSlide = (status) => {
// outputs a value between 0 and 1
console.log(status);
};

renderDrawer = () => {
return (
<View>
<Text>I am in the drawer!</Text>
</View>
);
};

render() {
return (
<View style={{ flex: 1 }}>
<DrawerLayout
drawerWidth={200}
drawerPosition={DrawerLayout.positions.Right}
drawerType="front"
drawerBackgroundColor="#ddd"
renderNavigationView={this.renderDrawer}
onDrawerSlide={this.handleDrawerSlide}>
<View>
<Text>Hello, it's me</Text>
</View>
</DrawerLayout>
</View>
);
}
}
```
Loading