Instawork / hyperview

Server-driven mobile apps with React Native
https://hyperview.org
MIT License
1.27k stars 66 forks source link

Quick question: would I be able to use the swipable tabs plugin with Hyperview? #369

Closed roelve closed 2 years ago

roelve commented 2 years ago

This one: https://www.npmjs.com/package/react-native-swipe-tabs

adamstep commented 2 years ago

Hi @roelve , I looked at the code for that library, it looks like it mainly handles swiping the tabs, but not a title bar at the top. Are you looking to support just the swiping of the views, or also the title bar?

roelve commented 2 years ago

Also the title bar, though knowing how to have the views swipe without it would also be a massive step forward for me.

adamstep commented 2 years ago

We implemented something similar at Instawork using the https://github.com/meliorence/react-native-snap-carousel library. Our use case was to have a carousel for a small UI on the screen, but I think a similar principle applies. Here's the custom element we added to our app to support this:

import Hyperview from 'hyperview';
import Carousel from 'react-native-snap-carousel';

const { width: WINDOW_WIDTH } = Dimensions.get('window');
const CAROUSEL_ITEM_TAG = 'carousel-item';

export default class HyperviewCarousel extends PureComponent {
  static namespaceURI = 'https://myapp.com/my-namespace';
  static localName = 'carousel';

  getCarouselItems = () => {
    return Array.from(
      this.props.element.getElementsByTagNameNS(HyperviewCarousel.namespaceURI, CAROUSEL_ITEM_TAG),
    );
  };

  renderCarouselItem = (carouselItemProps) => {
    return Hyperview.renderChildren(
      carouselItemProps.item,
      this.props.stylesheets,
      this.props.onUpdate,
      this.props.options,
    );
  };

  render() {
    const carouselItems = this.getCarouselItems();
    return (
      <View>
        <Carousel
          data={carouselItems}
          itemWidth={WINDOW_WIDTH}
          renderItem={this.renderCarouselItem}
          showsHorizontalScrollIndicator={false}
          sliderWidth={WINDOW_WIDTH}
        />
      </View>
    );
  }
}

Once you add and register this custom element with your RN app, you could use the following XML markup on your screens:

<view xmlns:my-app="https://myapp.com/my-namespace">
<my-app:carousel>
  <my-app:carousel-item>
      <text style="h6">Screen 1</text>
      <text style="b7">Sample Body Text</text>
  </my-app:carousel-item>
  <my-app:carousel-item>
    <view style="m-16 p-16 border rounded">
      <text style="h6">Screen 2</text>
      <text style="b7">Sample Body Text</text>
    </view>
  </my-app:carousel-item>
  <my-app:carousel-item>
    <view style="m-16 p-16 border rounded">
      <text style="h6">Screen 3</text>
      <text style="b7">Sample Body Text</text>
    </view>
  </my-app:carousel-item>
</my-app:carousel>
</view>