@janiscommerce/ui-native 1.13.3 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+ interface CollapsibleProps<HeaderProps = {}, ContentProps = {}> {
4
+ header: React.ComponentType<HeaderProps>;
5
+ content: React.ComponentType<ContentProps & {
6
+ index: number;
7
+ }>;
8
+ data?: Record<string, any>[];
9
+ pressableComponent?: React.ComponentType;
10
+ duration?: number;
11
+ onPressCallback?: null | (() => void);
12
+ wrapperStyle?: ViewStyle;
13
+ }
14
+ declare const Collapsible: React.FC<CollapsibleProps<{
15
+ isOpen: boolean;
16
+ }, {
17
+ isOpen?: boolean;
18
+ }>>;
19
+ export default Collapsible;
@@ -0,0 +1,63 @@
1
+ import List from '../List';
2
+ import React, { useState } from 'react';
3
+ import { StyleSheet, View, Pressable } from 'react-native';
4
+ import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
5
+ const Collapsible = ({ header: Header, content: Content, data = [], onPressCallback = null, pressableComponent: PressableComponent = Pressable, duration = 500, wrapperStyle = {}, }) => {
6
+ const isOpen = useSharedValue(false);
7
+ const [measuredHeight, setMeasuredHeight] = useState(0);
8
+ const contentHeight = useSharedValue(0);
9
+ const hasHeightBeenMeasured = !!measuredHeight;
10
+ const handleOpen = () => {
11
+ // istanbul ignore next
12
+ if (!isOpen.value && measuredHeight > 0) {
13
+ contentHeight.value = measuredHeight;
14
+ }
15
+ isOpen.value = !isOpen.value;
16
+ if (onPressCallback) {
17
+ onPressCallback();
18
+ }
19
+ };
20
+ const handleContentLayout = (e) => {
21
+ // istanbul ignore next
22
+ if (measuredHeight === 0) {
23
+ const newHeight = e.nativeEvent.layout.height;
24
+ setMeasuredHeight(newHeight);
25
+ contentHeight.value = newHeight;
26
+ }
27
+ };
28
+ // istanbul ignore next
29
+ const bodyStyle = useAnimatedStyle(() => ({
30
+ maxHeight: withTiming(isOpen.value ? contentHeight.value : 0, { duration }),
31
+ overflow: 'hidden',
32
+ }));
33
+ const styles = StyleSheet.create({
34
+ wrapperView: {
35
+ flex: 1,
36
+ width: '100%',
37
+ },
38
+ animatedView: {
39
+ overflow: 'hidden',
40
+ width: '100%',
41
+ },
42
+ contentWrapper: {
43
+ position: 'absolute',
44
+ opacity: 0,
45
+ },
46
+ });
47
+ const renderContent = (contentData) => {
48
+ const { item, index } = contentData;
49
+ return <Content {...item} index={index} isOpen={isOpen}/>;
50
+ };
51
+ return (<View style={[wrapperStyle, styles.wrapperView]}>
52
+ <PressableComponent onPress={handleOpen}>
53
+ <Header isOpen={isOpen.value}/>
54
+ </PressableComponent>
55
+ {!hasHeightBeenMeasured && (<View style={styles.contentWrapper} onLayout={handleContentLayout}>
56
+ <List data={data} renderComponent={renderContent} keyExtractor={(_, index) => String(index)} showsVerticalScrollIndicator={false}/>
57
+ </View>)}
58
+ <Animated.View style={[styles.animatedView, bodyStyle]}>
59
+ <List data={data} renderComponent={renderContent} keyExtractor={(_, index) => String(index)} showsVerticalScrollIndicator={false}/>
60
+ </Animated.View>
61
+ </View>);
62
+ };
63
+ export default Collapsible;
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ import { SwipeUpFlatList, SwipeUpScrollView, SwipeUpView } from './components/at
12
12
  import Text from './components/atoms/Text';
13
13
  import BaseInput from './components/atoms/BaseInput';
14
14
  import Typography from './components/atoms/Typography';
15
+ import Collapsible from './components/atoms/Collapsible';
15
16
  import Avatar from './components/molecules/Avatar';
16
17
  import Button from './components/molecules/Button';
17
18
  import Carousel from './components/molecules/Carousel';
@@ -29,4 +30,4 @@ import FullScreenMessage from './components/organisms/FullScreenMessage';
29
30
  import SwipeItemSelectionList from './components/organisms/SwipeItemSelectionList';
30
31
  import { palette } from './theme/palette';
31
32
  import * as getScale from './scale';
32
- export { Text, Avatar, CheckBox, Icon, Image, Input, Loading, Svg, StatusChip, palette, LoadingFullScreen, RadioButton, Select, SwipeUp, SwipeUpFlatList, SwipeUpScrollView, SwipeUpView, Carousel, ProgressBar, List, BaseButton, Button, getScale, LayoutWithBottomButtons, FullScreenMessage, Toast, configToast, SwipeList, ItemSelectionButton, SwipeItemSelectionList, MainCardList, BaseInput, Typography, };
33
+ export { Text, Avatar, CheckBox, Icon, Image, Input, Loading, Svg, StatusChip, palette, LoadingFullScreen, RadioButton, Select, SwipeUp, SwipeUpFlatList, SwipeUpScrollView, SwipeUpView, Carousel, ProgressBar, List, BaseButton, Button, getScale, LayoutWithBottomButtons, FullScreenMessage, Toast, configToast, SwipeList, ItemSelectionButton, SwipeItemSelectionList, MainCardList, BaseInput, Typography, Collapsible, };
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ import { SwipeUpFlatList, SwipeUpScrollView, SwipeUpView } from './components/at
13
13
  import Text from './components/atoms/Text';
14
14
  import BaseInput from './components/atoms/BaseInput';
15
15
  import Typography from './components/atoms/Typography';
16
+ import Collapsible from './components/atoms/Collapsible';
16
17
  // Molecules
17
18
  import Avatar from './components/molecules/Avatar';
18
19
  import Button from './components/molecules/Button';
@@ -33,4 +34,4 @@ import SwipeItemSelectionList from './components/organisms/SwipeItemSelectionLis
33
34
  // Misc
34
35
  import { palette } from './theme/palette';
35
36
  import * as getScale from './scale';
36
- export { Text, Avatar, CheckBox, Icon, Image, Input, Loading, Svg, StatusChip, palette, LoadingFullScreen, RadioButton, Select, SwipeUp, SwipeUpFlatList, SwipeUpScrollView, SwipeUpView, Carousel, ProgressBar, List, BaseButton, Button, getScale, LayoutWithBottomButtons, FullScreenMessage, Toast, configToast, SwipeList, ItemSelectionButton, SwipeItemSelectionList, MainCardList, BaseInput, Typography, };
37
+ export { Text, Avatar, CheckBox, Icon, Image, Input, Loading, Svg, StatusChip, palette, LoadingFullScreen, RadioButton, Select, SwipeUp, SwipeUpFlatList, SwipeUpScrollView, SwipeUpView, Carousel, ProgressBar, List, BaseButton, Button, getScale, LayoutWithBottomButtons, FullScreenMessage, Toast, configToast, SwipeList, ItemSelectionButton, SwipeItemSelectionList, MainCardList, BaseInput, Typography, Collapsible, };
@@ -1,2 +1,3 @@
1
1
  export declare const isObject: (obj: Object) => boolean;
2
2
  export declare const isDevEnv: () => boolean;
3
+ export declare const isArray: (arr: any[]) => boolean;
@@ -4,3 +4,4 @@ export const isDevEnv = () => {
4
4
  const { NODE_ENV } = env;
5
5
  return NODE_ENV !== 'production';
6
6
  };
7
+ export const isArray = (arr) => !!(arr instanceof Array);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@janiscommerce/ui-native",
3
- "version": "1.13.3",
3
+ "version": "1.14.0",
4
4
  "description": "components library for Janis app",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",