@tactics/toddle-styleguide 5.4.9 → 5.4.11

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/App.tsx CHANGED
@@ -80,8 +80,9 @@ import { SelectableListItemPreview } from './src/components/molecules/selectable
80
80
  import {
81
81
  SafeAreaProvider,
82
82
  } from 'react-native-safe-area-context';
83
- import {ContactAddress} from './src/components/molecules/contact-address/contact-address.component';
84
83
  import {ContactAddressPreview} from './src/components/molecules/contact-address/contact-address.preview';
84
+ import {IsSafePreview} from './src/components/atoms/safe-check/safe-check.preview';
85
+ import {SnapshotItemPreview} from './src/components/organisms/snapshot-item/snapshot-item.preview';
85
86
 
86
87
  const Stack = createNativeStackNavigator();
87
88
 
@@ -125,6 +126,10 @@ const HomeScreen = ({navigation}: {navigation: any}) => {
125
126
  title="Contact Info Card"
126
127
  onPress={() => navigation.push('person-info-card')}
127
128
  />
129
+ <ReactBtn
130
+ title="Snapshot Item"
131
+ onPress={() => navigation.push('snapshot-item')}
132
+ />
128
133
  <ReactBtn
129
134
  title="Contact Item"
130
135
  onPress={() => navigation.push('contact-item')}
@@ -133,6 +138,10 @@ const HomeScreen = ({navigation}: {navigation: any}) => {
133
138
  title="Contact Address"
134
139
  onPress={() => navigation.push('contact-address')}
135
140
  />
141
+ <ReactBtn
142
+ title="Safe Check"
143
+ onPress={() => navigation.push('safe-check')}
144
+ />
136
145
  <ReactBtn
137
146
  title="Contact Role"
138
147
  onPress={() => navigation.push('contact-role')}
@@ -522,6 +531,11 @@ function App() {
522
531
  }}>
523
532
  {() => <PersonInfoCardPreview />}
524
533
  </Stack.Screen>
534
+ <Stack.Screen name="snapshot-item" options={{
535
+ freezeOnBlur: false,
536
+ }}>
537
+ {() => <SnapshotItemPreview />}
538
+ </Stack.Screen>
525
539
  <Stack.Screen name="pill" options={{
526
540
  freezeOnBlur: false,
527
541
  }}>{() => <PillPreview />}</Stack.Screen>
@@ -637,6 +651,11 @@ function App() {
637
651
  }}>
638
652
  {() => <ContactAddressPreview />}
639
653
  </Stack.Screen>
654
+ <Stack.Screen name="safe-check" options={{
655
+ freezeOnBlur: false,
656
+ }}>
657
+ {() => <IsSafePreview />}
658
+ </Stack.Screen>
640
659
  </Stack.Navigator>
641
660
  </NavigationContainer>
642
661
  </ThemeCtx.Provider>
package/index.tsx CHANGED
@@ -127,6 +127,8 @@ import { DayInterface, DayOutputFormat } from './src/utilities/datetime/day.clas
127
127
  import { DateTime, DateTimeCalculation, DateTimeInterface, DateTimeOutputFormat } from './src/utilities/datetime/datetime.class';
128
128
  import { DateOnly, DateOnlyInterface, DateOnlyLocaleAwareOutputFormat, DateOnlyOutputFormat } from './src/utilities/datetime/dateonly.class';
129
129
  import { TimeSlotEmployeeSequence } from "./src/models/time-slot-employee-sequence";
130
+ import { SnapshotItem } from "./src/components/organisms/snapshot-item/snapshot-item.component";
131
+ import { SafeCheck } from "./src/components/atoms/safe-check/safe-check.component";
130
132
 
131
133
  // ================================
132
134
  // Exports
@@ -206,6 +208,8 @@ export {
206
208
  SwipeableContainer,
207
209
  SwipeableAction,
208
210
  Day,
211
+ SnapshotItem,
212
+ SafeCheck,
209
213
 
210
214
  // Enums
211
215
  BubbleAlignment,
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@tactics/toddle-styleguide",
3
- "version": "5.4.9",
3
+ "version": "5.4.11",
4
4
  "main": "index.tsx",
5
5
  "types": "index.d.ts",
6
6
  "prepublish": "tsc",
7
7
  "scripts": {
8
8
  "eas-build-pre-install": "corepack enable",
9
- "start": "./node_modules/.bin/tsc && ./node_modules/.bin/expo start",
9
+ "start": "./node_modules/.bin/tsc && npx expo start --dev-client",
10
10
  "test": "./node_modules/.bin/jest",
11
11
  "format": "./node_modules/.bin/prettier --write src/.",
12
12
  "types": "./node_modules/.bin/tsc index.tsx --declaration --allowJs --emitDeclarationOnly --esModuleInterop --jsx react-native --skipLibCheck --target es5",
13
- "android": "expo run:android",
14
- "ios": "expo run:ios"
13
+ "android": "npx expo run:android",
14
+ "ios": "npx expo run:ios"
15
15
  },
16
16
  "engineStrict": true,
17
17
  "engines": {
@@ -0,0 +1,38 @@
1
+ import {Pressable, PressableProps} from 'react-native';
2
+ import {useContext} from 'react';
3
+ import {ThemeCtx} from '../../../context/theme.context';
4
+ import {Stylesheet} from './safe-check.styles';
5
+ import React from 'react';
6
+ import {Icon} from '../../../icons/index';
7
+
8
+ interface SafeCheckProps extends PressableProps {
9
+ isSafe: boolean;
10
+ onPress?: () => void;
11
+ }
12
+
13
+ export const SafeCheck = ({
14
+ isSafe,
15
+ onPress,
16
+ ...props
17
+ }: SafeCheckProps) => {
18
+ const context = useContext(ThemeCtx);
19
+ const styles = Stylesheet(context, isSafe);
20
+
21
+ return (
22
+ <Pressable
23
+ onPress={() => {
24
+ if (onPress) {
25
+ onPress()
26
+ }
27
+ }}
28
+ {...props}
29
+ style={styles.container}
30
+ testID={'safe-check-test'}
31
+ >
32
+ {isSafe ?
33
+ <Icon color={'#FFFFFF'} style={'solid'} name={'check-circle'} /> :
34
+ <Icon color={'#000000'} style={'solid'} name={'exclamation'} />
35
+ }
36
+ </Pressable>
37
+ );
38
+ };
@@ -0,0 +1,22 @@
1
+ import {Text, View} from 'react-native';
2
+ import {useState} from 'react';
3
+ import React from 'react';
4
+ import {SafeCheck} from './safe-check.component';
5
+
6
+ export const IsSafePreview = () => {
7
+ const [firstSafe, setFirstSafe] = useState<boolean>(false);
8
+ const [secondSafe, setSecondSafe] = useState<boolean>(true);
9
+
10
+ return (
11
+ <View
12
+ style={{
13
+ flex: 1,
14
+ alignItems: 'center',
15
+ justifyContent: 'center',
16
+ }}
17
+ >
18
+ <SafeCheck isSafe={firstSafe} onPress={() => {setFirstSafe(!firstSafe)}}/>
19
+ <SafeCheck isSafe={secondSafe} onPress={() => {setSecondSafe(!secondSafe)}}/>
20
+ </View>
21
+ );
22
+ };
@@ -0,0 +1,18 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {Scale} from '../../../theme/scale/index';
3
+ import {Size} from '../../../types/size.enum';
4
+
5
+ export const Stylesheet = (context, isSafe) =>
6
+ StyleSheet.create({
7
+ container: {
8
+ overflow: 'hidden',
9
+ backgroundColor: isSafe
10
+ ? context.colors.ui.success.default
11
+ : context.colors.ui.lightgrey,
12
+ justifyContent: 'center',
13
+ alignItems: 'center',
14
+ width: 60,
15
+ height: 60,
16
+ borderRadius: 60 / 2,
17
+ },
18
+ });
@@ -0,0 +1,84 @@
1
+ import {ImageSourcePropType, View, ViewStyle, Text, PressableProps, Pressable} from 'react-native';
2
+ import React, {useCallback, useContext, useMemo} from "react";
3
+ import {ThemeCtx} from "../../../context/theme.context";
4
+ import {Stylesheet} from "./snapshot-item.styles";
5
+ import {Icon} from "../../../icons/index";
6
+ import {SafeCheck} from "../../atoms/safe-check/safe-check.component";
7
+ import {Paragraph, SmallText} from "../../atoms/paragraph-components";
8
+ import {Heading2} from "../../atoms/heading-components";
9
+
10
+ interface SnapshotItemProps extends PressableProps {
11
+ id: string;
12
+ name: string;
13
+ department: string;
14
+ isSafe: boolean;
15
+ onPressArrow: (id: string) => void;
16
+ onPressText: (id: string) => void;
17
+ }
18
+
19
+ export const SnapshotItem = ({
20
+ id,
21
+ name,
22
+ department,
23
+ isSafe,
24
+ onPressArrow,
25
+ onPressText,
26
+ ...props
27
+ }: SnapshotItemProps) => {
28
+ const context = useContext(ThemeCtx);
29
+ const styles = Stylesheet(context, isSafe);
30
+
31
+ const onPressTextCallback = useCallback(() => {
32
+ onPressText(id);
33
+ }, [id, onPressText]);
34
+
35
+ const onPressArrowCallback = useCallback(() => {
36
+ onPressArrow(id);
37
+ }, [id, onPressArrow]);
38
+
39
+ const textColor = useMemo(() => {
40
+ return context.colors.ui.black;
41
+ }, [isSafe]);
42
+
43
+ return (
44
+ <View style={styles.container}>
45
+ <View style={styles.pressableContainer}>
46
+ <Pressable
47
+ onPress={onPressTextCallback}
48
+ style={styles.innerContainer}
49
+ >
50
+ <View style={styles.pressableCheck}>
51
+ <SafeCheck
52
+ isSafe={isSafe}
53
+ onPress={() => onPressTextCallback()}
54
+ />
55
+ </View>
56
+ <View style={styles.pressableText}>
57
+ <View>
58
+ <Heading2
59
+ bold={true}
60
+ numberOfLines={1}
61
+ ellipsizeMode={'tail'}
62
+ textColor={textColor}
63
+ >
64
+ {name}
65
+ </Heading2>
66
+ <SmallText textColor={textColor}>{department}</SmallText>
67
+ </View>
68
+ </View>
69
+ </Pressable>
70
+ <Pressable
71
+ onPress={onPressArrowCallback}
72
+ style={styles.iconContainer}
73
+ >
74
+ <Icon
75
+ style={'regular'}
76
+ name={'chevron-right'}
77
+ size={20}
78
+ color={context.colors.ui.black}
79
+ />
80
+ </Pressable>
81
+ </View>
82
+ </View>
83
+ );
84
+ };
@@ -0,0 +1,40 @@
1
+ import React, {useState} from 'react';
2
+ import {SnapshotItem} from './snapshot-item.component';
3
+
4
+ const {View} = require('react-native');
5
+
6
+ export const SnapshotItemPreview = ({}: {}) => {
7
+
8
+ const [firstSafe, setFirstSafe] = useState<boolean>(false);
9
+ const [secondSafe, setSecondSafe] = useState<boolean>(true);
10
+
11
+
12
+ return (
13
+ <View
14
+ style={{
15
+ flex: 1,
16
+ backgroundColor: 'white',
17
+ paddingTop: 150,
18
+ }}
19
+ >
20
+ <View>
21
+ <SnapshotItem
22
+ id={'1'}
23
+ name={'Joske vermeulen'}
24
+ department={"Kleutertjes"}
25
+ isSafe={firstSafe}
26
+ onPressArrow={() => {console.log('navigate to details')}}
27
+ onPressText={() => {setFirstSafe(!firstSafe)}}
28
+ />
29
+ <SnapshotItem
30
+ id={'2'}
31
+ name={'Patrick Loveren'}
32
+ department={"Peuters"}
33
+ isSafe={secondSafe}
34
+ onPressArrow={() => {console.log('navigate to details')}}
35
+ onPressText={() => {setSecondSafe(!secondSafe)}}
36
+ />
37
+ </View>
38
+ </View>
39
+ );
40
+ };
@@ -0,0 +1,44 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {Scale} from '../../../theme/scale/index';
3
+
4
+ export const Stylesheet = (context, isSafe) =>
5
+ StyleSheet.create({
6
+ container: {
7
+ width: '100%',
8
+ borderTopRightRadius: Scale.l,
9
+ borderBottomRightRadius: Scale.l,
10
+ borderTopLeftRadius: Scale.xl,
11
+ borderBottomLeftRadius: Scale.xl,
12
+ flexDirection: 'column',
13
+ backgroundColor: context.colors.ui.white,
14
+ minHeight: 100
15
+ },
16
+ innerContainer: {
17
+ flex: 1,
18
+ padding: Scale.xs,
19
+ flexDirection: 'row',
20
+ borderTopRightRadius: Scale.l,
21
+ borderBottomRightRadius: Scale.l,
22
+ borderTopLeftRadius: Scale.xxl,
23
+ borderBottomLeftRadius: Scale.xxl,
24
+ alignItems: 'center',
25
+ },
26
+ pressableContainer: {
27
+ flex: 1,
28
+ flexDirection: 'row',
29
+ alignItems: 'center',
30
+ },
31
+ pressableCheck: {},
32
+ pressableText: {
33
+ marginLeft: Scale.l,
34
+ },
35
+ iconContainer: {
36
+ alignItems: 'flex-end',
37
+ justifyContent: 'center',
38
+ paddingRight: Scale.xs,
39
+ width: Scale.m * 4,
40
+ height: '100%',
41
+ borderTopRightRadius: Scale.l,
42
+ borderBottomRightRadius: Scale.l,
43
+ },
44
+ });
@@ -1,53 +1,88 @@
1
- import React, {Children, isValidElement, useContext, useEffect, useMemo, useState} from 'react';
2
- import {Animated, Dimensions, LayoutChangeEvent, Platform, StatusBar, View, ViewProps} from 'react-native';
3
- import {Backdrop} from '../../atoms/backdrop/backdrop.component';
4
- import {Stylesheet} from './popover-action.styles';
5
- import {Swipe} from '../../molecules/swipe/swipe.component';
6
- import {ThemeCtx} from '../../../context/theme.context';
7
- import {Foreground} from '../popover/components';
1
+ import React, {
2
+ Children,
3
+ isValidElement,
4
+ ReactNode,
5
+ useContext,
6
+ useEffect,
7
+ useMemo,
8
+ useState,
9
+ } from 'react';
10
+ import {
11
+ Animated,
12
+ Dimensions,
13
+ LayoutChangeEvent,
14
+ Platform,
15
+ StatusBar,
16
+ View,
17
+ ViewProps,
18
+ } from 'react-native';
19
+ import { Backdrop } from '../../atoms/backdrop/backdrop.component';
20
+ import { Stylesheet } from './popover-action.styles';
21
+ import { Swipe } from '../../molecules/swipe/swipe.component';
22
+ import { ThemeCtx } from '../../../context/theme.context';
8
23
 
9
24
  type PopOverActionProps = {
10
25
  isVisible: boolean;
11
26
  touchBackDrop: (value: boolean) => void;
12
27
  children?: React.ReactNode;
13
28
  };
14
- export const PopOverAction = ({
15
- isVisible,
16
- children,
17
- touchBackDrop,
18
- }: PopOverActionProps) => {
19
29
 
30
+ export const PopOverAction = ({
31
+ isVisible,
32
+ children,
33
+ touchBackDrop,
34
+ }: PopOverActionProps) => {
20
35
  const [windowHeight, setWindowHeight] = useState(
21
36
  Dimensions.get('window').height
22
37
  );
23
- const [elementSize, setElementSize] = useState({width: 0, height: 0});
38
+ const [elementSize, setElementSize] = useState({ width: 0, height: 0 });
24
39
  const [currentChildIndex, setCurrentChildIndex] = useState(0);
25
- const [childDimensions, setChildDimensions] = useState<any[]>([]);
40
+ const [childDimensions, setChildDimensions] = useState<
41
+ LayoutChangeEvent['nativeEvent']['layout'][]
42
+ >([]);
43
+
44
+ const handleChildLayout = (
45
+ index: number,
46
+ layout: LayoutChangeEvent['nativeEvent']['layout']
47
+ ) => {
48
+ setChildDimensions((prev) => {
49
+ const updated = [...prev];
50
+ updated[index] = layout;
51
+ return updated;
52
+ });
53
+ };
26
54
 
27
- const handleChildLayout = (index: number, layout: any) => {
28
- const updatedDimensions = [...childDimensions];
29
- updatedDimensions[index] = layout;
55
+ function renderChildrenWithLayout(
56
+ children: ReactNode,
57
+ handleChildLayout: (
58
+ index: number,
59
+ layout: LayoutChangeEvent['nativeEvent']['layout']
60
+ ) => void
61
+ ) {
62
+ return Children.map(children, (child, index) => {
63
+ if (!isValidElement<ViewProps>(child)) return child;
30
64
 
31
- setChildDimensions(updatedDimensions);
32
- };
65
+ // Merge any existing onLayout the child might have
66
+ const existingOnLayout = child.props.onLayout;
33
67
 
34
- const renderChildren = Children.map(children, (child, index) => {
35
- if (isValidElement<ViewProps>(child)) {
36
68
  return React.cloneElement(child, {
37
- onLayout: (event: LayoutChangeEvent) =>
38
- handleChildLayout(index, event.nativeEvent.layout),
69
+ onLayout: (event: LayoutChangeEvent) => {
70
+ existingOnLayout?.(event);
71
+ handleChildLayout(index, event.nativeEvent.layout);
72
+ },
39
73
  });
40
- }
41
- return null;
42
- });
74
+ });
75
+ }
43
76
 
44
77
  const handleChildIndexChange = (index: number) => {
45
78
  setCurrentChildIndex(index);
46
79
 
47
80
  const childDimension = childDimensions[index];
48
81
  if (childDimension) {
49
- const {width, height} = childDimension;
50
- setElementSize({width: width, height: height});
82
+ setElementSize({
83
+ width: childDimension.width,
84
+ height: childDimension.height,
85
+ });
51
86
  }
52
87
  };
53
88
 
@@ -61,11 +96,7 @@ export const PopOverAction = ({
61
96
  };
62
97
 
63
98
  updateWindowHeight();
64
-
65
- const subscription = Dimensions.addEventListener(
66
- 'change',
67
- updateWindowHeight
68
- );
99
+ const subscription = Dimensions.addEventListener('change', updateWindowHeight);
69
100
 
70
101
  return () => subscription?.remove();
71
102
  }, []);
@@ -74,7 +105,7 @@ export const PopOverAction = ({
74
105
  const styles = Stylesheet(context);
75
106
 
76
107
  const elementHeight = Math.round(elementSize.height);
77
- const maxHeight = Math.round(windowHeight / 100) * 80;
108
+ const maxHeight = Math.round(windowHeight * 0.8);
78
109
  const translateYStartingPoint = windowHeight;
79
110
  const saveHeight = elementHeight > maxHeight ? maxHeight : elementHeight;
80
111
 
@@ -99,13 +130,12 @@ export const PopOverAction = ({
99
130
  }).start();
100
131
  };
101
132
 
102
- if (isVisible) {
103
- open();
104
- } else {
105
- close();
106
- }
133
+ useEffect(() => {
134
+ if (isVisible) open();
135
+ else close();
136
+ }, [isVisible, saveHeight]);
107
137
 
108
- const transform = [{translateY: translateY}];
138
+ const transform = [{ translateY }];
109
139
 
110
140
  return (
111
141
  <View
@@ -117,11 +147,13 @@ export const PopOverAction = ({
117
147
  <Animated.View
118
148
  style={[
119
149
  styles.slidePanelContainer,
120
- {maxHeight: maxHeight},
121
- {transform: transform},
150
+ { maxHeight },
151
+ { transform },
122
152
  ]}
123
153
  >
124
- <Swipe onIndexChange={handleChildIndexChange}>{renderChildren}</Swipe>
154
+ <Swipe onIndexChange={handleChildIndexChange}>
155
+ {renderChildrenWithLayout(children, handleChildLayout)}
156
+ </Swipe>
125
157
  </Animated.View>
126
158
  </View>
127
159
  );