unicorn-demo-app 7.11.3 → 7.12.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.
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -66,6 +66,9 @@ module.exports = {
|
|
|
66
66
|
get HintsScreen() {
|
|
67
67
|
return require('./screens/componentScreens/HintsScreen').default;
|
|
68
68
|
},
|
|
69
|
+
get HorizontalSortableListScreen() {
|
|
70
|
+
return require('./screens/componentScreens/HorizontalSortableListScreen').default;
|
|
71
|
+
},
|
|
69
72
|
get IconScreen() {
|
|
70
73
|
return require('./screens/componentScreens/IconScreen').default;
|
|
71
74
|
},
|
|
@@ -99,6 +99,7 @@ export const navigationData = {
|
|
|
99
99
|
{title: 'Conversation List', tags: 'list conversation', screen: 'unicorn.lists.ConversationListScreen'},
|
|
100
100
|
{title: 'Drawer', tags: 'drawer', screen: 'unicorn.components.DrawerScreen'},
|
|
101
101
|
{title: 'SortableList', tags: 'sortable list drag', screen: 'unicorn.components.SortableListScreen'},
|
|
102
|
+
{title: 'HorizontalSortableList', tags: 'sortable horizontal list drag', screen: 'unicorn.components.HorizontalSortableListScreen'},
|
|
102
103
|
{title: 'GridList', tags: 'grid list', screen: 'unicorn.components.GridListScreen'},
|
|
103
104
|
{title: 'SortableGridList', tags: 'sort grid list drag', screen: 'unicorn.components.SortableGridListScreen'}
|
|
104
105
|
]
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React, {useCallback, useState, useRef} from 'react';
|
|
2
|
+
import {StyleSheet} from 'react-native';
|
|
3
|
+
import {SortableList, View, Text, Colors, Button, Card, BorderRadiuses} from 'react-native-ui-lib';
|
|
4
|
+
import {renderHeader} from '../ExampleScreenPresenter';
|
|
5
|
+
import products from '../../data/products';
|
|
6
|
+
|
|
7
|
+
const data = products.map((product, index) => ({...product, locked: index === 3}));
|
|
8
|
+
type Item = (typeof data)[0];
|
|
9
|
+
|
|
10
|
+
const HorizontalSortableListScreen = () => {
|
|
11
|
+
const [items, setItems] = useState<Item[]>(data);
|
|
12
|
+
const [selectedItems, setSelectedItems] = useState<Item[]>([]);
|
|
13
|
+
const [removedItems, setRemovedItems] = useState<Item[]>([]);
|
|
14
|
+
const orderedItems = useRef<Item[]>(data);
|
|
15
|
+
|
|
16
|
+
const toggleItemSelection = useCallback((item: Item) => {
|
|
17
|
+
if (selectedItems.includes(item)) {
|
|
18
|
+
setSelectedItems(selectedItems.filter(selectedItem => ![item.id].includes(selectedItem.id)));
|
|
19
|
+
} else {
|
|
20
|
+
setSelectedItems(selectedItems.concat(item));
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
[selectedItems, setSelectedItems]);
|
|
24
|
+
|
|
25
|
+
const addItem = useCallback(() => {
|
|
26
|
+
if (removedItems.length > 0) {
|
|
27
|
+
orderedItems.current = orderedItems.current.concat(removedItems[0]);
|
|
28
|
+
setItems(orderedItems.current);
|
|
29
|
+
setRemovedItems(removedItems.slice(1));
|
|
30
|
+
}
|
|
31
|
+
}, [removedItems, setItems, setRemovedItems]);
|
|
32
|
+
|
|
33
|
+
const removeSelectedItems = useCallback(() => {
|
|
34
|
+
setRemovedItems(removedItems.concat(selectedItems));
|
|
35
|
+
setSelectedItems([]);
|
|
36
|
+
orderedItems.current = orderedItems.current.filter(item => !selectedItems.includes(item));
|
|
37
|
+
setItems(orderedItems.current);
|
|
38
|
+
}, [setRemovedItems, removedItems, selectedItems, setItems, setSelectedItems]);
|
|
39
|
+
|
|
40
|
+
const keyExtractor = useCallback((item: Item) => {
|
|
41
|
+
return `${item.id}`;
|
|
42
|
+
}, []);
|
|
43
|
+
|
|
44
|
+
const onOrderChange = useCallback((newData: Item[]) => {
|
|
45
|
+
console.log('New order:', newData);
|
|
46
|
+
orderedItems.current = newData;
|
|
47
|
+
}, []);
|
|
48
|
+
|
|
49
|
+
const renderItem = useCallback(({item, index: _index}: {item: Item; index: number}) => {
|
|
50
|
+
const selected = selectedItems.includes(item);
|
|
51
|
+
const {locked} = item;
|
|
52
|
+
const Container = locked ? View : Card;
|
|
53
|
+
return (
|
|
54
|
+
<Container
|
|
55
|
+
style={styles.itemContainer}
|
|
56
|
+
onPress={() => toggleItemSelection(item)}
|
|
57
|
+
customValue={item.id}
|
|
58
|
+
selected={selected}
|
|
59
|
+
margin-s1
|
|
60
|
+
>
|
|
61
|
+
<Card.Section
|
|
62
|
+
imageSource={{uri: item.mediaUrl}}
|
|
63
|
+
imageStyle={styles.itemImage}
|
|
64
|
+
imageProps={{
|
|
65
|
+
customOverlayContent: (
|
|
66
|
+
<Text margin-s1={!locked} h1={!locked} h4={locked} center={locked} orange30>
|
|
67
|
+
{locked ? 'Locked' : item.id}
|
|
68
|
+
</Text>
|
|
69
|
+
)
|
|
70
|
+
}}
|
|
71
|
+
/>
|
|
72
|
+
</Container>
|
|
73
|
+
);
|
|
74
|
+
},
|
|
75
|
+
[selectedItems, toggleItemSelection]);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<View flex bg-$backgroundDefault>
|
|
79
|
+
{renderHeader('Sortable List', {'margin-10': true})}
|
|
80
|
+
<View row center marginB-s2>
|
|
81
|
+
<Button label="Add Item" size={Button.sizes.xSmall} disabled={removedItems.length === 0} onPress={addItem}/>
|
|
82
|
+
<Button
|
|
83
|
+
label="Remove Items"
|
|
84
|
+
size={Button.sizes.xSmall}
|
|
85
|
+
disabled={selectedItems.length === 0}
|
|
86
|
+
marginL-s3
|
|
87
|
+
onPress={removeSelectedItems}
|
|
88
|
+
/>
|
|
89
|
+
</View>
|
|
90
|
+
<View flex useSafeArea>
|
|
91
|
+
<SortableList
|
|
92
|
+
horizontal
|
|
93
|
+
data={items}
|
|
94
|
+
renderItem={renderItem}
|
|
95
|
+
keyExtractor={keyExtractor}
|
|
96
|
+
onOrderChange={onOrderChange}
|
|
97
|
+
scale={1.02}
|
|
98
|
+
/>
|
|
99
|
+
</View>
|
|
100
|
+
</View>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export default HorizontalSortableListScreen;
|
|
105
|
+
const styles = StyleSheet.create({
|
|
106
|
+
itemContainer: {
|
|
107
|
+
overflow: 'hidden',
|
|
108
|
+
borderColor: Colors.$outlineDefault,
|
|
109
|
+
borderBottomWidth: 1
|
|
110
|
+
},
|
|
111
|
+
selectedItemContainer: {
|
|
112
|
+
borderLeftColor: Colors.$outlinePrimary,
|
|
113
|
+
borderLeftWidth: 5
|
|
114
|
+
},
|
|
115
|
+
itemImage: {
|
|
116
|
+
width: 80,
|
|
117
|
+
height: 80,
|
|
118
|
+
borderRadius: BorderRadiuses.br10
|
|
119
|
+
}
|
|
120
|
+
});
|
|
@@ -50,6 +50,7 @@ export function registerScreens(registrar) {
|
|
|
50
50
|
registrar('unicorn.components.SliderScreen', () => require('./SliderScreen').default);
|
|
51
51
|
registrar('unicorn.components.SortableGridListScreen', () => require('./SortableGridListScreen').default);
|
|
52
52
|
registrar('unicorn.components.SortableListScreen', () => require('./SortableListScreen').default);
|
|
53
|
+
registrar('unicorn.components.HorizontalSortableListScreen', () => require('./HorizontalSortableListScreen').default);
|
|
53
54
|
registrar('unicorn.components.StackAggregatorScreen', () => require('./StackAggregatorScreen').default);
|
|
54
55
|
registrar('unicorn.components.StepperScreen', () => require('./StepperScreen').default);
|
|
55
56
|
registrar('unicorn.components.SwitchScreen', () => require('./SwitchScreen').default);
|
|
@@ -19,7 +19,6 @@ const TOAST_MESSAGES = {
|
|
|
19
19
|
offline: 'Check Your Internet Connection'
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
// TODO: "ReactImageView: Image source "null" doesn't exist" (Android + preset "none")
|
|
23
22
|
class ToastsScreen extends Component {
|
|
24
23
|
showToast = false; // keep this state in class instance for immediate response
|
|
25
24
|
state = {
|