-1

In React Native, is there any way to resize a Drawer with a resize handle by dragging the edge of the Drawer. For example, like in the Slack screenshot here. This is a very common use case but see no implementation of it anywhere online.

Slack Example Screenshot

I think it's possible with Pan Gestures but don't see a way to get a divider between the Drawer and Screen View.

mklement0
  • 382,024
  • 64
  • 607
  • 775
jg42233
  • 1
  • 3

2 Answers2

0

To achieve a resizable drawer with a resize handle in React Native, you can utilize the PanResponder API to handle the pan gestures and update the width of the drawer dynamically. Here's a general approach to implementing this feature:

  1. Set up the initial state:

    state = {
      drawerWidth: INITIAL_DRAWER_WIDTH,
    };
    
  2. Create a pan responder to handle the gestures:

    panResponder = PanResponder.create({
      onMoveShouldSetPanResponder: () => true,
      onPanResponderMove: (_, { dx }) => {
        const newDrawerWidth = this.state.drawerWidth - dx;
        // You can add additional checks here to ensure the drawer width stays within desired limits
    
        this.setState({ drawerWidth: newDrawerWidth });
      },
    });
    
  3. Render the components with the resizable drawer:

    render() {
      return (
        <View style={styles.container}>
          <View
            style={[
              styles.drawer,
              { width: this.state.drawerWidth },
            ]}
            {...this.panResponder.panHandlers}
          >
            {/* Content of the resizable drawer */}
          </View>
          <View style={styles.screen}>
            {/* Content of the screen view */}
          </View>
        </View>
      );
    }
    
  4. Style the components:

    const styles = StyleSheet.create({
      container: {
        flex: 1,
        flexDirection: 'row',
      },
      drawer: {
        backgroundColor: '#F2F2F2',
        borderRightWidth: 1,
        borderRightColor: '#CCCCCC',
      },
      screen: {
        flex: 1,
      },
    });
    

In the above code, INITIAL_DRAWER_WIDTH represents the initial width of the drawer, and you can customize it to suit your requirements. The onPanResponderMove function is responsible for updating the drawer width based on the horizontal movement during the pan gesture.

By attaching the pan responder to the resizable drawer view and updating its width dynamically, you can achieve the desired resizable behavior with a resize handle in React Native.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    This (and your other recent answers) looks like ChatGPT – DavidW Jun 21 '23 at 08:23
  • 1
    Welcome to Stack Overflow! Most or all of your 14 answers appear likely to have been entirely or partially written by AI (e.g., ChatGPT). Please be aware that [posting of AI-generated content is banned here](//meta.stackoverflow.com/q/421831). If you used an AI tool to assist with any answer, I would encourage you to delete it. Thanks! – NotTheDr01ds Jun 21 '23 at 23:35
  • 1
    **Readers should review this answer carefully and critically, as AI-generated information often contains fundamental errors and misinformation.** If you observe quality issues and/or have reason to believe that this answer was generated by AI, please leave feedback accordingly. The moderation team can use your help to identify quality issues. m – NotTheDr01ds Jun 21 '23 at 23:35
0

Thanks SugarFreeBeef, based on that I made a slight modification so it works by dragging a handle on the edge. Here is a working example

import {Animated, PanResponder, StyleSheet, Text, View} from "react-native";
import React, {useState} from "react";
import {PanGestureHandler} from "react-native-gesture-handler";

export default function Page(state) {

  const [drawerWidth, setdrawerWidth] = useState(200)

  const panResponder = PanResponder.create({
    onMoveShouldSetPanResponder: () => true,
    onPanResponderMove: (_, { dx }) => {
      const newDrawerWidth = drawerWidth + dx;
      setdrawerWidth(newDrawerWidth);
    },
  });

  return (
      <View style={styles.container}>
        <View style={[ styles.drawer, { width: drawerWidth } ]}>
          <Text>Content of the resizable drawer</Text>
        </View>
        <PanGestureHandler>
          <Animated.View style={[ styles.drawerHandle ]} {...panResponder.panHandlers}>
          </Animated.View>
        </PanGestureHandler>
        <View style={styles.screen}>
          <Text>Content of Screen</Text>
        </View>
      </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
  },
  drawer: {
    backgroundColor: '#F2F2F2',
    borderRightWidth: 1,
    borderRightColor: '#CCCCCC',
    zIndex: 1
  },
  drawerHandle: {
    height: 50,
    width: 10,
    marginTop: 100,
    marginLeft: -5,
    backgroundColor: '#000',
    borderRightWidth: 1,
    borderRightColor: '#000',
    zIndex: 2,
    cursor: 'col-resize'
  },
  screen: {
    flex: 1,
  },
});
jg42233
  • 1
  • 3