Application Android et IOS pour l'amicale des élèves
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TabIcon.tsx 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import * as React from 'react';
  20. import {View} from 'react-native';
  21. import {TouchableRipple, withTheme} from 'react-native-paper';
  22. import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
  23. import * as Animatable from 'react-native-animatable';
  24. type PropsType = {
  25. focused: boolean;
  26. color: string;
  27. label: string;
  28. icon: string;
  29. onPress: () => void;
  30. onLongPress: () => void;
  31. theme: ReactNativePaper.Theme;
  32. extraData: null | boolean | number | string;
  33. };
  34. /**
  35. * Abstraction layer for Agenda component, using custom configuration
  36. */
  37. class TabIcon extends React.Component<PropsType> {
  38. firstRender: boolean;
  39. constructor(props: PropsType) {
  40. super(props);
  41. Animatable.initializeRegistryWithDefinitions({
  42. focusIn: {
  43. '0': {
  44. // @ts-ignore
  45. scale: 1,
  46. translateY: 0,
  47. },
  48. '0.9': {
  49. scale: 1.3,
  50. translateY: 7,
  51. },
  52. '1': {
  53. scale: 1.2,
  54. translateY: 6,
  55. },
  56. },
  57. focusOut: {
  58. '0': {
  59. // @ts-ignore
  60. scale: 1.2,
  61. translateY: 6,
  62. },
  63. '1': {
  64. scale: 1,
  65. translateY: 0,
  66. },
  67. },
  68. });
  69. this.firstRender = true;
  70. }
  71. componentDidMount() {
  72. this.firstRender = false;
  73. }
  74. shouldComponentUpdate(nextProps: PropsType): boolean {
  75. const {props} = this;
  76. return (
  77. nextProps.focused !== props.focused ||
  78. nextProps.theme.dark !== props.theme.dark ||
  79. nextProps.extraData !== props.extraData
  80. );
  81. }
  82. render() {
  83. const {props} = this;
  84. return (
  85. <TouchableRipple
  86. onPress={props.onPress}
  87. onLongPress={props.onLongPress}
  88. rippleColor={props.theme.colors.primary}
  89. borderless
  90. style={{
  91. flex: 1,
  92. justifyContent: 'center',
  93. borderRadius: 10,
  94. }}>
  95. <View>
  96. <Animatable.View
  97. duration={200}
  98. easing="ease-out"
  99. animation={props.focused ? 'focusIn' : 'focusOut'}
  100. useNativeDriver>
  101. <MaterialCommunityIcons
  102. name={props.icon}
  103. color={props.color}
  104. size={26}
  105. style={{
  106. marginLeft: 'auto',
  107. marginRight: 'auto',
  108. }}
  109. />
  110. </Animatable.View>
  111. <Animatable.Text
  112. animation={props.focused ? 'fadeOutDown' : 'fadeIn'}
  113. useNativeDriver
  114. style={{
  115. color: props.color,
  116. marginLeft: 'auto',
  117. marginRight: 'auto',
  118. fontSize: 10,
  119. }}>
  120. {props.label}
  121. </Animatable.Text>
  122. </View>
  123. </TouchableRipple>
  124. );
  125. }
  126. }
  127. export default withTheme(TabIcon);