chore: change prettier config (#19)

This commit is contained in:
Jakub Grzywacz 2021-08-11 10:13:38 +02:00 committed by GitHub
parent c4a8ed36fc
commit f68fcf720f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 688 additions and 862 deletions

View File

@ -1,3 +1,3 @@
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
}

View File

@ -1,5 +1,5 @@
const path = require('path');
const pak = require('../package.json');
const path = require('path')
const pak = require('../package.json')
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
@ -14,4 +14,4 @@ module.exports = {
},
],
],
};
}

View File

@ -1,5 +1,5 @@
import { AppRegistry } from 'react-native';
import App from './src/App';
import { name as appName } from './app.json';
import { AppRegistry } from 'react-native'
import App from './src/App'
import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App);
AppRegistry.registerComponent(appName, () => App)

View File

@ -494,8 +494,8 @@ SPEC CHECKSUMS:
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
FlipperKit: 57764956d2f0f972c1af5075a9c8f05ca5b12349
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
Folly: aeb27d02cdff07ca01f8a8a5a6dd5bcaf6be6f70
glog: 2ad46e202fbaa5641fceb4b2af37dcd88fd8762d
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e

View File

@ -1,13 +1,13 @@
const path = require('path');
const blacklist = require('metro-config/src/defaults/blacklist');
const escape = require('escape-string-regexp');
const pak = require('../package.json');
const path = require('path')
const blacklist = require('metro-config/src/defaults/blacklist')
const escape = require('escape-string-regexp')
const pak = require('../package.json')
const root = path.resolve(__dirname, '..');
const root = path.resolve(__dirname, '..')
const modules = Object.keys({
...pak.peerDependencies,
});
})
module.exports = {
projectRoot: __dirname,
@ -17,15 +17,12 @@ module.exports = {
// So we blacklist them at the root, and alias them to the versions in example's node_modules
resolver: {
blacklistRE: blacklist(
modules.map(
(m) =>
new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
)
modules.map((m) => new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`))
),
extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, 'node_modules', name);
return acc;
acc[name] = path.join(__dirname, 'node_modules', name)
return acc
}, {}),
},
@ -37,4 +34,4 @@ module.exports = {
},
}),
},
};
}

View File

@ -1,20 +1,20 @@
import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Examples from './Examples/Examples';
import Basic from './Basic/Basic';
import Dark from './Dark/Dark';
import Translated from './Translated/Translated';
import DisabledCategories from './DisabledCategories/DisabledCategories';
import StaticModal from './StaticModal/StaticModal';
import Static from './Static/Static';
import EnableRecently from './EnableRecently/EnableRecently';
import TopCategory from './TopCategory/TopCategory';
import BottomCategory from './BottomCategory/BottomCategory';
import SearchBar from './SearchBar/SearchBar';
import 'react-native-gesture-handler'
import * as React from 'react'
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import Examples from './Examples/Examples'
import Basic from './Basic/Basic'
import Dark from './Dark/Dark'
import Translated from './Translated/Translated'
import DisabledCategories from './DisabledCategories/DisabledCategories'
import StaticModal from './StaticModal/StaticModal'
import Static from './Static/Static'
import EnableRecently from './EnableRecently/EnableRecently'
import TopCategory from './TopCategory/TopCategory'
import BottomCategory from './BottomCategory/BottomCategory'
import SearchBar from './SearchBar/SearchBar'
const Stack = createStackNavigator();
const Stack = createStackNavigator()
export default () => {
return (
<NavigationContainer>
@ -27,13 +27,10 @@ export default () => {
<Stack.Screen name="TopCategory" component={TopCategory} />
<Stack.Screen name="BottomCategory" component={BottomCategory} />
<Stack.Screen name="Translated" component={Translated} />
<Stack.Screen
name="DisabledCategories"
component={DisabledCategories}
/>
<Stack.Screen name="DisabledCategories" component={DisabledCategories} />
<Stack.Screen name="StaticModal" component={StaticModal} />
<Stack.Screen name="Static" component={Static} />
</Stack.Navigator>
</NavigationContainer>
);
};
)
}

View File

@ -1,18 +1,18 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const Basic = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
console.log(emoji);
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
console.log(emoji)
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
@ -26,8 +26,8 @@ const Basic = () => {
onClose={() => setIsModalOpen(false)}
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -38,6 +38,6 @@ const styles = StyleSheet.create({
margin: 64,
fontSize: 18,
},
});
})
export default Basic;
export default Basic

View File

@ -1,17 +1,17 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const BottomCategory = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
@ -26,8 +26,8 @@ const BottomCategory = () => {
categoryPosition="bottom"
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -38,6 +38,6 @@ const styles = StyleSheet.create({
margin: 64,
fontSize: 18,
},
});
})
export default BottomCategory;
export default BottomCategory

View File

@ -1,18 +1,18 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const Dark = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
console.log(emoji);
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
console.log(emoji)
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
@ -34,8 +34,8 @@ const Dark = () => {
headerStyles={styles.headerStyles}
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -58,6 +58,6 @@ const styles = StyleSheet.create({
color: '#fff',
fontSize: 16,
},
});
})
export default Dark;
export default Dark

View File

@ -1,18 +1,18 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const DisabledCategories = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
console.log(emoji);
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
console.log(emoji)
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
@ -27,8 +27,8 @@ const DisabledCategories = () => {
disabledCategory={['activities', 'flags', 'objects', 'symbols']}
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -39,6 +39,6 @@ const styles = StyleSheet.create({
margin: 64,
fontSize: 18,
},
});
})
export default DisabledCategories;
export default DisabledCategories

View File

@ -1,18 +1,18 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const EnableRecently = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
console.log(emoji);
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
console.log(emoji)
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
@ -27,8 +27,8 @@ const EnableRecently = () => {
enableRecentlyUsed
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -39,6 +39,6 @@ const styles = StyleSheet.create({
margin: 64,
fontSize: 18,
},
});
})
export default EnableRecently;
export default EnableRecently

View File

@ -1,23 +1,23 @@
import * as React from 'react';
import { View, Button } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import type { StackScreenProps } from '@react-navigation/stack';
import * as React from 'react'
import { View, Button } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import type { StackScreenProps } from '@react-navigation/stack'
type RootStackParamList = {
Examples: undefined;
Basic: undefined;
Dark: undefined;
Translated: undefined;
DisabledCategories: undefined;
StaticModal: undefined;
Static: undefined;
EnableRecently: undefined;
TopCategory: undefined;
BottomCategory: undefined;
SearchBar: undefined;
};
Examples: undefined
Basic: undefined
Dark: undefined
Translated: undefined
DisabledCategories: undefined
StaticModal: undefined
Static: undefined
EnableRecently: undefined
TopCategory: undefined
BottomCategory: undefined
SearchBar: undefined
}
type Props = StackScreenProps<RootStackParamList, 'Examples'>;
type Props = StackScreenProps<RootStackParamList, 'Examples'>
const Examples = ({ navigation }: Props) => {
return (
@ -25,10 +25,7 @@ const Examples = ({ navigation }: Props) => {
<View>
<Button title="Basic" onPress={() => navigation.navigate('Basic')} />
<Button title="Dark" onPress={() => navigation.navigate('Dark')} />
<Button
title="Translated"
onPress={() => navigation.navigate('Translated')}
/>
<Button title="Translated" onPress={() => navigation.navigate('Translated')} />
<Button
title="Disabled Categories"
onPress={() => navigation.navigate('DisabledCategories')}
@ -37,28 +34,16 @@ const Examples = ({ navigation }: Props) => {
title="Static Modal (wihtout knob)"
onPress={() => navigation.navigate('StaticModal')}
/>
<Button
title="Static Component"
onPress={() => navigation.navigate('Static')}
/>
<Button title="Static Component" onPress={() => navigation.navigate('Static')} />
<Button
title="Enable recently used"
onPress={() => navigation.navigate('EnableRecently')}
/>
<Button
title="Category Top"
onPress={() => navigation.navigate('TopCategory')}
/>
<Button
title="Category Bottom"
onPress={() => navigation.navigate('BottomCategory')}
/>
<Button
title="Search Bar"
onPress={() => navigation.navigate('SearchBar')}
/>
<Button title="Category Top" onPress={() => navigation.navigate('TopCategory')} />
<Button title="Category Bottom" onPress={() => navigation.navigate('BottomCategory')} />
<Button title="Search Bar" onPress={() => navigation.navigate('SearchBar')} />
</View>
</SafeAreaView>
);
};
export default Examples;
)
}
export default Examples

View File

@ -1,18 +1,18 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const SearchBar = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
console.log(emoji);
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
console.log(emoji)
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
@ -27,8 +27,8 @@ const SearchBar = () => {
enableSearchBar
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -39,6 +39,6 @@ const styles = StyleSheet.create({
margin: 64,
fontSize: 18,
},
});
})
export default SearchBar;
export default SearchBar

View File

@ -1,29 +1,26 @@
import * as React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { EmojiKeyboard } from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, View } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import { EmojiKeyboard } from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const Static = () => {
const [result, setResult] = React.useState<string>();
const [result, setResult] = React.useState<string>()
const handlePick = (emoji: EmojiType) => {
setResult(emoji.emoji);
};
setResult(emoji.emoji)
}
return (
<SafeAreaView style={styles.container}>
<View style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
</View>
<View style={styles.container}>
<EmojiKeyboard
onEmojiSelected={handlePick}
containerStyles={styles.keyboardContainer}
/>
<EmojiKeyboard onEmojiSelected={handlePick} containerStyles={styles.keyboardContainer} />
</View>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -37,6 +34,6 @@ const styles = StyleSheet.create({
keyboardContainer: {
borderRadius: 0,
},
});
})
export default Static;
export default Static

View File

@ -1,18 +1,18 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const StaticModal = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
console.log(emoji);
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
console.log(emoji)
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
@ -28,8 +28,8 @@ const StaticModal = () => {
defaultHeight="65%"
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -40,6 +40,6 @@ const styles = StyleSheet.create({
margin: 64,
fontSize: 18,
},
});
})
export default StaticModal;
export default StaticModal

View File

@ -1,17 +1,17 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const TopCategory = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Result: {result}</Text>
@ -26,8 +26,8 @@ const TopCategory = () => {
categoryPosition="top"
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -38,6 +38,6 @@ const styles = StyleSheet.create({
margin: 64,
fontSize: 18,
},
});
})
export default TopCategory;
export default TopCategory

View File

@ -1,18 +1,18 @@
import * as React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import EmojiPicker, { pl } from 'rn-emoji-keyboard';
import type { EmojiType } from 'src/types';
import * as React from 'react'
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiPicker, { pl } from 'rn-emoji-keyboard'
import type { EmojiType } from 'src/types'
const Translated = () => {
const [result, setResult] = React.useState<string>();
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false);
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)
const handlePick = (emoji: EmojiType) => {
console.log(emoji);
setResult(emoji.emoji);
setIsModalOpen((prev) => !prev);
};
console.log(emoji)
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Emotka: {result}</Text>
@ -27,8 +27,8 @@ const Translated = () => {
translation={pl}
/>
</SafeAreaView>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -39,6 +39,6 @@ const styles = StyleSheet.create({
margin: 64,
fontSize: 18,
},
});
})
export default Translated;
export default Translated

View File

@ -52,6 +52,7 @@
"@commitlint/config-conventional": "^11.0.0",
"@react-native-community/eslint-config": "^2.0.0",
"@release-it/conventional-changelog": "^2.0.0",
"@twgdev/prettier-config": "^1.0.2",
"@types/jest": "^26.0.0",
"@types/react": "^16.9.19",
"@types/react-native": "0.62.13",
@ -116,31 +117,13 @@
"extends": [
"@react-native-community",
"prettier"
],
"rules": {
"prettier/prettier": [
"error",
{
"quoteProps": "consistent",
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false
}
]
}
]
},
"eslintIgnore": [
"node_modules/",
"lib/"
],
"prettier": {
"quoteProps": "consistent",
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false
},
"prettier": "@twgdev/prettier-config",
"react-native-builder-bob": {
"source": "src",
"output": "lib",

18
scripts/bootstrap.js vendored
View File

@ -1,24 +1,24 @@
const path = require('path');
const child_process = require('child_process');
const path = require('path')
const child_process = require('child_process')
const root = path.resolve(__dirname, '..');
const args = process.argv.slice(2);
const root = path.resolve(__dirname, '..')
const args = process.argv.slice(2)
const options = {
cwd: process.cwd(),
env: process.env,
stdio: 'inherit',
encoding: 'utf-8',
};
}
let result;
let result
if (process.cwd() !== root || args.length) {
// We're not in the root of the project, or additional arguments were passed
// In this case, forward the command to `yarn`
result = child_process.spawnSync('yarn', args, options);
result = child_process.spawnSync('yarn', args, options)
} else {
// If `yarn` is run without arguments, perform bootstrap
result = child_process.spawnSync('yarn', ['bootstrap'], options);
result = child_process.spawnSync('yarn', ['bootstrap'], options)
}
process.exitCode = result.status;
process.exitCode = result.status

View File

@ -1,24 +1,20 @@
const json = require('unicode-emoji-json/data-by-group.json');
const fs = require('fs');
const json = require('unicode-emoji-json/data-by-group.json')
const fs = require('fs')
const newArray = [];
const newArray = []
for (const [key, value] of Object.entries(json)) {
const newData = value.map((emoji) => ({
emoji: emoji.emoji,
name: emoji.name,
v: emoji.unicode_version,
}));
}))
newArray.push({
title: key.replace(' & ', '_').replace(' ', '_').toLocaleLowerCase(),
data: newData,
});
})
}
fs.writeFile(
'./src/assets/emojis.json',
JSON.stringify(newArray),
function (err) {
if (err) return console.log(err);
console.log('emojis.json successfully saved to assets folder');
}
);
fs.writeFile('./src/assets/emojis.json', JSON.stringify(newArray), function (err) {
if (err) return console.log(err)
console.log('emojis.json successfully saved to assets folder')
})

View File

@ -1,19 +1,16 @@
import * as React from 'react';
import { EmojiStaticKeyboard } from './components/EmojiStaticKeyboard';
import { KeyboardProvider } from './contexts/KeyboardProvider';
import type {
KeyboardProps,
OnEmojiSelected,
} from './contexts/KeyboardContext';
import * as React from 'react'
import { EmojiStaticKeyboard } from './components/EmojiStaticKeyboard'
import { KeyboardProvider } from './contexts/KeyboardProvider'
import type { KeyboardProps, OnEmojiSelected } from './contexts/KeyboardContext'
type EmojiKeyboardProps = {
onEmojiSelected: OnEmojiSelected;
} & Partial<KeyboardProps>;
onEmojiSelected: OnEmojiSelected
} & Partial<KeyboardProps>
export const EmojiKeyboard = (props: EmojiKeyboardProps) => {
return (
<KeyboardProvider {...props}>
<EmojiStaticKeyboard />
</KeyboardProvider>
);
};
)
}

View File

@ -1,15 +1,12 @@
import * as React from 'react';
import { Animated, useWindowDimensions } from 'react-native';
import { EmojiStaticKeyboard } from './components/EmojiStaticKeyboard';
import { Knob } from './components/Knob';
import {
defaultKeyboardContext,
KeyboardProvider,
} from './contexts/KeyboardProvider';
import type { KeyboardProps } from './contexts/KeyboardContext';
import type { EmojiType } from './types';
import { ModalWithBackdrop } from './components/ModalWithBackdrop';
import { getHeight } from './utils';
import * as React from 'react'
import { Animated, useWindowDimensions } from 'react-native'
import { EmojiStaticKeyboard } from './components/EmojiStaticKeyboard'
import { Knob } from './components/Knob'
import { defaultKeyboardContext, KeyboardProvider } from './contexts/KeyboardProvider'
import type { KeyboardProps } from './contexts/KeyboardContext'
import type { EmojiType } from './types'
import { ModalWithBackdrop } from './components/ModalWithBackdrop'
import { getHeight } from './utils'
export const EmojiPicker = ({
onEmojiSelected,
@ -19,55 +16,49 @@ export const EmojiPicker = ({
defaultHeight = defaultKeyboardContext.defaultHeight,
...props
}: KeyboardProps) => {
const { height: screenHeight } = useWindowDimensions();
const offsetY = React.useRef(new Animated.Value(0)).current;
const height = React.useRef(
new Animated.Value(getHeight(defaultHeight, screenHeight))
).current;
const translateY = React.useRef(new Animated.Value(0)).current;
const { height: screenHeight } = useWindowDimensions()
const offsetY = React.useRef(new Animated.Value(0)).current
const height = React.useRef(new Animated.Value(getHeight(defaultHeight, screenHeight))).current
const translateY = React.useRef(new Animated.Value(0)).current
React.useEffect(() => {
Animated.timing(translateY, {
toValue: open ? 0 : screenHeight,
useNativeDriver: true,
duration: 500,
}).start();
}, [open, screenHeight, translateY]);
}).start()
}, [open, screenHeight, translateY])
const close = () => {
height.setValue(getHeight(defaultHeight, screenHeight));
offsetY.setValue(0);
onClose();
};
height.setValue(getHeight(defaultHeight, screenHeight))
offsetY.setValue(0)
onClose()
}
return (
<KeyboardProvider
onEmojiSelected={(emoji: EmojiType) => {
onEmojiSelected(emoji);
close();
onEmojiSelected(emoji)
close()
}}
open={open}
onClose={close}
expandable={expandable}
defaultHeight={defaultHeight}
{...props}
>
{...props}>
<ModalWithBackdrop isOpen={open} backdropPress={close}>
<>
{expandable && (
<Knob height={height} offsetY={offsetY} onClose={onClose} />
)}
{expandable && <Knob height={height} offsetY={offsetY} onClose={onClose} />}
<Animated.View
style={[
{
height: Animated.subtract(height, offsetY),
},
]}
>
]}>
<EmojiStaticKeyboard />
</Animated.View>
</>
</ModalWithBackdrop>
</KeyboardProvider>
);
};
)
}

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="23" height="23" viewBox="0 0 24 24" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -10,4 +10,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="23" height="23" viewBox="0 0 24 24" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import Svg, { FillProps, Path } from 'react-native-svg';
import * as React from 'react'
import Svg, { FillProps, Path } from 'react-native-svg'
export default ({ fill }: FillProps) => (
<Svg width="22" height="22" viewBox="0 0 22 22" fill="none">
@ -8,4 +8,4 @@ export default ({ fill }: FillProps) => (
fill={fill}
/>
</Svg>
);
)

View File

@ -1,20 +1,16 @@
import * as React from 'react';
import { Animated, FlatList, StyleSheet, View, ViewStyle } from 'react-native';
import { useKeyboardStore } from '../store/useKeyboardStore';
import { defaultKeyboardContext } from '../contexts/KeyboardProvider';
import { KeyboardContext } from '../contexts/KeyboardContext';
import {
CATEGORIES_NAVIGATION,
CategoryNavigationItem,
CategoryTypes,
} from '../types';
import { CategoryItem } from './CategoryItem';
import { exhaustiveTypeCheck, getCategoryIndex } from '../utils';
import * as React from 'react'
import { Animated, FlatList, StyleSheet, View, ViewStyle } from 'react-native'
import { useKeyboardStore } from '../store/useKeyboardStore'
import { defaultKeyboardContext } from '../contexts/KeyboardProvider'
import { KeyboardContext } from '../contexts/KeyboardContext'
import { CATEGORIES_NAVIGATION, CategoryNavigationItem, CategoryTypes } from '../types'
import { CategoryItem } from './CategoryItem'
import { exhaustiveTypeCheck, getCategoryIndex } from '../utils'
type CategoriesProps = {
flatListRef: React.RefObject<FlatList>;
scrollNav: Animated.Value;
};
flatListRef: React.RefObject<FlatList>
scrollNav: Animated.Value
}
export const Categories = ({ flatListRef, scrollNav }: CategoriesProps) => {
const {
@ -26,27 +22,21 @@ export const Categories = ({ flatListRef, scrollNav }: CategoriesProps) => {
enableRecentlyUsed,
categoryPosition,
searchPhrase,
} = React.useContext(KeyboardContext);
const { keyboardState } = useKeyboardStore();
} = React.useContext(KeyboardContext)
const { keyboardState } = useKeyboardStore()
const handleScrollToCategory = React.useCallback(
(category: CategoryTypes) => {
flatListRef?.current?.scrollToIndex(
getCategoryIndex(disabledCategory, category)
);
flatListRef?.current?.scrollToIndex(getCategoryIndex(disabledCategory, category))
},
[disabledCategory, flatListRef]
);
)
const renderItem = React.useCallback(
({ item, index }: { item: CategoryNavigationItem; index: number }) => (
<CategoryItem
item={item}
index={index}
handleScrollToCategory={handleScrollToCategory}
/>
<CategoryItem item={item} index={index} handleScrollToCategory={handleScrollToCategory} />
),
[handleScrollToCategory]
);
)
const activeIndicator = React.useCallback(
() => (
@ -63,51 +53,45 @@ export const Categories = ({ flatListRef, scrollNav }: CategoriesProps) => {
/>
),
[activeCategoryContainerColor, scrollNav]
);
)
const getStylesBasedOnPosition = () => {
const style: ViewStyle[] = [styles.navigation];
const style: ViewStyle[] = [styles.navigation]
switch (categoryPosition) {
case 'floating':
style.push(styles.navigationFloating);
break;
style.push(styles.navigationFloating)
break
case 'top':
style.push(styles.navigationTop);
break;
style.push(styles.navigationTop)
break
case 'bottom':
style.push(styles.navigationBottom);
break;
style.push(styles.navigationBottom)
break
default:
exhaustiveTypeCheck(categoryPosition);
break;
exhaustiveTypeCheck(categoryPosition)
break
}
if (
categoryContainerColor !==
defaultKeyboardContext.categoryContainerColor ||
categoryContainerColor !== defaultKeyboardContext.categoryContainerColor ||
categoryPosition === 'floating'
)
style.push({
backgroundColor: categoryContainerColor,
});
return style;
};
})
return style
}
const renderData = React.useMemo(() => {
const isRecentlyUsedHidden = (category: CategoryTypes) =>
category === 'recently_used' &&
(keyboardState.recentlyUsed.length === 0 || !enableRecentlyUsed);
(keyboardState.recentlyUsed.length === 0 || !enableRecentlyUsed)
return CATEGORIES_NAVIGATION.filter(({ category }) => {
if (searchPhrase === '' && category === 'search') return false;
if (isRecentlyUsedHidden(category)) return false;
return !disabledCategory.includes(category);
});
}, [
disabledCategory,
enableRecentlyUsed,
keyboardState.recentlyUsed.length,
searchPhrase,
]);
if (searchPhrase === '' && category === 'search') return false
if (isRecentlyUsedHidden(category)) return false
return !disabledCategory.includes(category)
})
}, [disabledCategory, enableRecentlyUsed, keyboardState.recentlyUsed.length, searchPhrase])
return (
<View style={[categoryPosition === 'floating' && styles.floating]}>
@ -126,8 +110,8 @@ export const Categories = ({ flatListRef, scrollNav }: CategoriesProps) => {
/>
</View>
</View>
);
};
)
}
const styles = StyleSheet.create({
floating: {
@ -175,4 +159,4 @@ const styles = StyleSheet.create({
width: 28,
height: 28,
},
});
})

View File

@ -1,31 +1,23 @@
import * as React from 'react';
import { View, StyleSheet, TouchableOpacity } from 'react-native';
import { KeyboardContext } from '../contexts/KeyboardContext';
import type { CategoryNavigationItem, CategoryTypes } from '../types';
import { Icon } from './Icon';
import * as React from 'react'
import { View, StyleSheet, TouchableOpacity } from 'react-native'
import { KeyboardContext } from '../contexts/KeyboardContext'
import type { CategoryNavigationItem, CategoryTypes } from '../types'
import { Icon } from './Icon'
type CategoryItemProps = {
item: CategoryNavigationItem;
index: number;
handleScrollToCategory: (category: CategoryTypes) => void;
};
item: CategoryNavigationItem
index: number
handleScrollToCategory: (category: CategoryTypes) => void
}
export const CategoryItem = ({
item,
index,
handleScrollToCategory,
}: CategoryItemProps) => {
const {
activeCategoryIndex,
categoryColor,
activeCategoryColor,
setActiveCategoryIndex,
} = React.useContext(KeyboardContext);
export const CategoryItem = ({ item, index, handleScrollToCategory }: CategoryItemProps) => {
const { activeCategoryIndex, categoryColor, activeCategoryColor, setActiveCategoryIndex } =
React.useContext(KeyboardContext)
const handleSelect = () => {
handleScrollToCategory(item.category);
setActiveCategoryIndex(index);
};
handleScrollToCategory(item.category)
setActiveCategoryIndex(index)
}
return (
<TouchableOpacity onPress={handleSelect}>
@ -38,8 +30,8 @@ export const CategoryItem = ({
/>
</View>
</TouchableOpacity>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -51,4 +43,4 @@ const styles = StyleSheet.create({
borderRadius: 6,
},
icon: { textAlign: 'center' },
});
})

View File

@ -1,24 +1,20 @@
import * as React from 'react';
import * as React from 'react'
import { StyleSheet, View, Text, FlatList } from 'react-native';
import type { EmojisByCategory, EmojiType, JsonEmoji } from '../types';
import { SingleEmoji } from './SingleEmoji';
import { KeyboardContext } from '../contexts/KeyboardContext';
import { useKeyboardStore } from '../store/useKeyboardStore';
import { parseEmoji } from '../utils';
import { StyleSheet, View, Text, FlatList } from 'react-native'
import type { EmojisByCategory, EmojiType, JsonEmoji } from '../types'
import { SingleEmoji } from './SingleEmoji'
import { KeyboardContext } from '../contexts/KeyboardContext'
import { useKeyboardStore } from '../store/useKeyboardStore'
import { parseEmoji } from '../utils'
const emptyEmoji = {
emoji: '',
name: 'blank emoji',
slug: 'blank_emoji',
unicode_version: '0',
};
}
export const EmojiCategory = ({
item: { title, data },
}: {
item: EmojisByCategory;
}) => {
export const EmojiCategory = ({ item: { title, data } }: { item: EmojisByCategory }) => {
const {
onEmojiSelected,
emojiSize,
@ -28,55 +24,47 @@ export const EmojiCategory = ({
headerStyles,
translation,
categoryPosition,
} = React.useContext(KeyboardContext);
} = React.useContext(KeyboardContext)
const { setKeyboardState } = useKeyboardStore();
const { setKeyboardState } = useKeyboardStore()
const [empty, setEmpty] = React.useState<EmojiType[]>([]);
const [empty, setEmpty] = React.useState<EmojiType[]>([])
React.useEffect(() => {
if (data.length % numberOfColumns) {
const fillWithEmpty = new Array(
numberOfColumns - (data.length % numberOfColumns)
).fill(emptyEmoji);
setEmpty(fillWithEmpty);
const fillWithEmpty = new Array(numberOfColumns - (data.length % numberOfColumns)).fill(
emptyEmoji
)
setEmpty(fillWithEmpty)
}
}, [numberOfColumns, data]);
}, [numberOfColumns, data])
const getItemLayout = (_: EmojiType[] | null | undefined, index: number) => ({
length: emojiSize ? emojiSize : 0,
offset: emojiSize * Math.ceil(index / numberOfColumns),
index,
});
})
const handleEmojiPress = React.useCallback(
(emoji: JsonEmoji) => {
if (emoji.name === 'blank emoji') return;
const parsedEmoji = parseEmoji(emoji);
onEmojiSelected(parsedEmoji);
setKeyboardState({ type: 'RECENT_EMOJI_ADD', payload: emoji });
if (emoji.name === 'blank emoji') return
const parsedEmoji = parseEmoji(emoji)
onEmojiSelected(parsedEmoji)
setKeyboardState({ type: 'RECENT_EMOJI_ADD', payload: emoji })
},
[onEmojiSelected, setKeyboardState]
);
)
const renderItem = React.useCallback(
(props) => (
<SingleEmoji
{...props}
onPress={() => handleEmojiPress(props.item)}
emojiSize={emojiSize}
/>
<SingleEmoji {...props} onPress={() => handleEmojiPress(props.item)} emojiSize={emojiSize} />
),
[emojiSize, handleEmojiPress]
);
)
return (
<View style={[styles.container, { width: width }]}>
{!hideHeader && (
<Text style={[styles.sectionTitle, headerStyles]}>
{translation[title]}
</Text>
)}
{!hideHeader && <Text style={[styles.sectionTitle, headerStyles]}>{translation[title]}</Text>}
<FlatList
data={[...data, ...empty]}
keyExtractor={(emoji) => emoji.name}
@ -85,19 +73,13 @@ export const EmojiCategory = ({
removeClippedSubviews={true}
getItemLayout={getItemLayout}
ListFooterComponent={() => (
<View
style={
categoryPosition === 'floating'
? styles.footerFloating
: styles.footer
}
/>
<View style={categoryPosition === 'floating' ? styles.footerFloating : styles.footer} />
)}
windowSize={20}
/>
</View>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -113,4 +95,4 @@ const styles = StyleSheet.create({
},
footer: { height: 8 },
footerFloating: { height: 70 },
});
})

View File

@ -1,24 +1,18 @@
import * as React from 'react';
import * as React from 'react'
import {
StyleSheet,
View,
FlatList,
useWindowDimensions,
Animated,
} from 'react-native';
import type { CategoryTypes, EmojisByCategory } from '../types';
import { EmojiCategory } from './EmojiCategory';
import { KeyboardContext } from '../contexts/KeyboardContext';
import { Categories } from './Categories';
import emojisByGroup from '../assets/emojis.json';
import { SearchBar } from './SearchBar';
import { useKeyboardStore } from '../store/useKeyboardStore';
import { StyleSheet, View, FlatList, useWindowDimensions, Animated } from 'react-native'
import type { CategoryTypes, EmojisByCategory } from '../types'
import { EmojiCategory } from './EmojiCategory'
import { KeyboardContext } from '../contexts/KeyboardContext'
import { Categories } from './Categories'
import emojisByGroup from '../assets/emojis.json'
import { SearchBar } from './SearchBar'
import { useKeyboardStore } from '../store/useKeyboardStore'
const CATEGORY_ELEMENT_WIDTH = 37;
const CATEGORY_ELEMENT_WIDTH = 37
export const EmojiStaticKeyboard = () => {
const { width } = useWindowDimensions();
const { width } = useWindowDimensions()
const {
activeCategoryIndex,
containerStyles,
@ -29,41 +23,35 @@ export const EmojiStaticKeyboard = () => {
searchPhrase,
setActiveCategoryIndex,
enableRecentlyUsed,
} = React.useContext(KeyboardContext);
const { keyboardState } = useKeyboardStore();
const flatListRef = React.useRef<FlatList>(null);
const scrollNav = React.useRef(new Animated.Value(0)).current;
} = React.useContext(KeyboardContext)
const { keyboardState } = useKeyboardStore()
const flatListRef = React.useRef<FlatList>(null)
const scrollNav = React.useRef(new Animated.Value(0)).current
const getItemLayout = (
_: CategoryTypes[] | null | undefined,
index: number
) => ({
const getItemLayout = (_: CategoryTypes[] | null | undefined, index: number) => ({
length: width,
offset: width * index,
index,
});
})
const renderItem = React.useCallback(
(props) => <EmojiCategory {...props} />,
[]
);
const renderItem = React.useCallback((props) => <EmojiCategory {...props} />, [])
React.useEffect(() => {
Animated.spring(scrollNav, {
toValue: activeCategoryIndex * CATEGORY_ELEMENT_WIDTH,
useNativeDriver: true,
}).start();
}, [activeCategoryIndex, scrollNav]);
}).start()
}, [activeCategoryIndex, scrollNav])
const renderList = React.useMemo(() => {
const data = emojisByGroup.filter((category) => {
const title = category.title as CategoryTypes;
return !disabledCategory.includes(title);
});
const title = category.title as CategoryTypes
return !disabledCategory.includes(title)
})
if (keyboardState.recentlyUsed.length && enableRecentlyUsed) {
data.push({
title: 'recently_used',
data: keyboardState.recentlyUsed,
});
})
}
data.push({
title: 'search',
@ -71,24 +59,19 @@ export const EmojiStaticKeyboard = () => {
.map((group) => group.data)
.flat()
.filter((emoji) => {
if (searchPhrase && searchPhrase.length < 2) return false;
return emoji.name.toLowerCase().includes(searchPhrase.toLowerCase());
if (searchPhrase && searchPhrase.length < 2) return false
return emoji.name.toLowerCase().includes(searchPhrase.toLowerCase())
}),
});
return data;
}, [
disabledCategory,
enableRecentlyUsed,
keyboardState.recentlyUsed,
searchPhrase,
]);
})
return data
}, [disabledCategory, enableRecentlyUsed, keyboardState.recentlyUsed, searchPhrase])
React.useEffect(() => {
if (searchPhrase !== '') {
flatListRef.current?.scrollToEnd();
setActiveCategoryIndex(renderList.length - 1);
flatListRef.current?.scrollToEnd()
setActiveCategoryIndex(renderList.length - 1)
}
}, [renderList, searchPhrase, setActiveCategoryIndex]);
}, [renderList, searchPhrase, setActiveCategoryIndex])
return (
<View
@ -97,8 +80,7 @@ export const EmojiStaticKeyboard = () => {
styles.containerShadow,
categoryPosition === 'top' && styles.containerReverse,
containerStyles,
]}
>
]}>
{enableSearchBar && <SearchBar flatListRef={flatListRef} />}
<Animated.FlatList
extraData={[keyboardState.recentlyUsed.length, searchPhrase]}
@ -120,8 +102,8 @@ export const EmojiStaticKeyboard = () => {
/>
<Categories flatListRef={flatListRef} scrollNav={scrollNav} />
</View>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -137,4 +119,4 @@ const styles = StyleSheet.create({
shadowRadius: 5,
elevation: 10,
},
});
})

View File

@ -1,18 +1,18 @@
import * as React from 'react';
import Flag from '../assets/Flag';
import Football from '../assets/Football';
import Lightbulb from '../assets/Lightbulb';
import Pizza from '../assets/Pizza';
import Plane from '../assets/Plane';
import Smile from '../assets/Smile';
import Trees from '../assets/Trees';
import Ban from '../assets/Ban';
import Users from '../assets/Users';
import Search from '../assets/Search';
import Close from '../assets/Close';
import Clock from '../assets/Clock';
import type { IconNames } from '../types';
import { exhaustiveTypeCheck } from '../utils';
import * as React from 'react'
import Flag from '../assets/Flag'
import Football from '../assets/Football'
import Lightbulb from '../assets/Lightbulb'
import Pizza from '../assets/Pizza'
import Plane from '../assets/Plane'
import Smile from '../assets/Smile'
import Trees from '../assets/Trees'
import Ban from '../assets/Ban'
import Users from '../assets/Users'
import Search from '../assets/Search'
import Close from '../assets/Close'
import Clock from '../assets/Clock'
import type { IconNames } from '../types'
import { exhaustiveTypeCheck } from '../utils'
export const Icon = ({
iconName,
@ -20,39 +20,39 @@ export const Icon = ({
normalColor,
activeColor,
}: {
iconName: IconNames | 'Close';
isActive: boolean;
normalColor: string;
activeColor: string;
iconName: IconNames | 'Close'
isActive: boolean
normalColor: string
activeColor: string
}) => {
const color = isActive ? activeColor : normalColor;
const color = isActive ? activeColor : normalColor
switch (iconName) {
case 'Smile':
return <Smile fill={color} />;
return <Smile fill={color} />
case 'Trees':
return <Trees fill={color} />;
return <Trees fill={color} />
case 'Pizza':
return <Pizza fill={color} />;
return <Pizza fill={color} />
case 'Plane':
return <Plane fill={color} />;
return <Plane fill={color} />
case 'Football':
return <Football fill={color} />;
return <Football fill={color} />
case 'Lightbulb':
return <Lightbulb fill={color} />;
return <Lightbulb fill={color} />
case 'Flag':
return <Flag fill={color} />;
return <Flag fill={color} />
case 'Ban':
return <Ban fill={color} />;
return <Ban fill={color} />
case 'Users':
return <Users fill={color} />;
return <Users fill={color} />
case 'Search':
return <Search fill={color} />;
return <Search fill={color} />
case 'Close':
return <Close fill={color} />;
return <Close fill={color} />
case 'Clock':
return <Clock fill={color} />;
return <Clock fill={color} />
default:
exhaustiveTypeCheck(iconName);
return null;
exhaustiveTypeCheck(iconName)
return null
}
};
}

View File

@ -1,24 +1,17 @@
import * as React from 'react';
import {
Animated,
useWindowDimensions,
StyleSheet,
View,
PanResponder,
} from 'react-native';
import { getHeight } from '../utils';
import { KeyboardContext } from '../contexts/KeyboardContext';
import * as React from 'react'
import { Animated, useWindowDimensions, StyleSheet, View, PanResponder } from 'react-native'
import { getHeight } from '../utils'
import { KeyboardContext } from '../contexts/KeyboardContext'
type KnobProps = {
offsetY: Animated.Value;
height: Animated.Value;
onClose: () => void;
};
offsetY: Animated.Value
height: Animated.Value
onClose: () => void
}
export const Knob = ({ offsetY, height, onClose }: KnobProps) => {
const { height: screenHeight } = useWindowDimensions();
const { expandedHeight, defaultHeight, knobStyles } =
React.useContext(KeyboardContext);
const { height: screenHeight } = useWindowDimensions()
const { expandedHeight, defaultHeight, knobStyles } = React.useContext(KeyboardContext)
const panResponder = React.useRef(
PanResponder.create({
@ -34,28 +27,28 @@ export const Knob = ({ offsetY, height, onClose }: KnobProps) => {
Animated.spring(offsetY, {
useNativeDriver: false,
toValue: 0,
}).start();
}).start()
if (gestureState.dy < -50) {
Animated.spring(height, {
useNativeDriver: false,
toValue: getHeight(expandedHeight, screenHeight),
}).start();
}).start()
} else if (gestureState.dy > 150) {
height.setValue(getHeight(defaultHeight, screenHeight));
offsetY.setValue(0);
onClose();
height.setValue(getHeight(defaultHeight, screenHeight))
offsetY.setValue(0)
onClose()
} else {
Animated.spring(height, {
useNativeDriver: false,
toValue: getHeight(defaultHeight, screenHeight),
}).start();
}).start()
}
},
onShouldBlockNativeResponder: () => {
return true;
return true
},
})
).current;
).current
return (
<View {...panResponder.panHandlers}>
@ -63,8 +56,8 @@ export const Knob = ({ offsetY, height, onClose }: KnobProps) => {
<Animated.View style={[styles.knob, knobStyles]} />
</View>
</View>
);
};
)
}
const styles = StyleSheet.create({
panContainer: {
@ -86,4 +79,4 @@ const styles = StyleSheet.create({
shadowOffset: { width: 0, height: 0 },
shadowRadius: 5,
},
});
})

View File

@ -1,4 +1,4 @@
import * as React from 'react';
import * as React from 'react'
import {
SafeAreaView,
Modal,
@ -7,58 +7,47 @@ import {
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import { KeyboardContext } from '../contexts/KeyboardContext';
import { useTimeout } from '../hooks/useTimeout';
} from 'react-native'
import { KeyboardContext } from '../contexts/KeyboardContext'
import { useTimeout } from '../hooks/useTimeout'
type ModalWithBackdropProps = {
isOpen: boolean;
backdropPress: () => void;
children: React.ReactNode;
};
isOpen: boolean
backdropPress: () => void
children: React.ReactNode
}
export const ModalWithBackdrop = ({
isOpen,
backdropPress,
children,
}: ModalWithBackdropProps) => {
const { height: screenHeight } = useWindowDimensions();
const translateY = React.useRef(new Animated.Value(screenHeight)).current;
const { backdropColor } = React.useContext(KeyboardContext);
const handleTimeout = useTimeout();
export const ModalWithBackdrop = ({ isOpen, backdropPress, children }: ModalWithBackdropProps) => {
const { height: screenHeight } = useWindowDimensions()
const translateY = React.useRef(new Animated.Value(screenHeight)).current
const { backdropColor } = React.useContext(KeyboardContext)
const handleTimeout = useTimeout()
React.useEffect(() => {
Animated.spring(translateY, {
toValue: isOpen ? 0 : screenHeight,
useNativeDriver: true,
}).start();
}, [isOpen, screenHeight, translateY]);
}).start()
}, [isOpen, screenHeight, translateY])
const handleClose = () => {
Animated.spring(translateY, {
toValue: screenHeight,
useNativeDriver: true,
}).start();
handleTimeout(() => backdropPress(), 200);
};
}).start()
handleTimeout(() => backdropPress(), 200)
}
return (
<Modal visible={isOpen} animationType="fade" transparent={true}>
<TouchableOpacity
style={styles.modalContainer}
activeOpacity={1}
onPress={handleClose}
>
<View
style={[styles.modalContainer, { backgroundColor: backdropColor }]}
>
<TouchableOpacity style={styles.modalContainer} activeOpacity={1} onPress={handleClose}>
<View style={[styles.modalContainer, { backgroundColor: backdropColor }]}>
<SafeAreaView style={styles.modalContainer}>
<TouchableOpacity activeOpacity={1}>
<Animated.View
style={{
transform: [{ translateY }],
}}
>
}}>
{children}
</Animated.View>
</TouchableOpacity>
@ -66,8 +55,8 @@ export const ModalWithBackdrop = ({
</View>
</TouchableOpacity>
</Modal>
);
};
)
}
const styles = StyleSheet.create({
modalContainer: { flex: 1, justifyContent: 'flex-end' },
@ -80,4 +69,4 @@ const styles = StyleSheet.create({
shadowRadius: 5,
elevation: 10,
},
});
})

View File

@ -1,17 +1,11 @@
import * as React from 'react';
import {
View,
StyleSheet,
TextInput,
TouchableOpacity,
FlatList,
} from 'react-native';
import { KeyboardContext } from '../contexts/KeyboardContext';
import { Icon } from './Icon';
import * as React from 'react'
import { View, StyleSheet, TextInput, TouchableOpacity, FlatList } from 'react-native'
import { KeyboardContext } from '../contexts/KeyboardContext'
import { Icon } from './Icon'
type SearchBarProps = {
flatListRef: React.RefObject<FlatList>;
};
flatListRef: React.RefObject<FlatList>
}
export const SearchBar = ({ flatListRef }: SearchBarProps) => {
const {
@ -23,18 +17,18 @@ export const SearchBar = ({ flatListRef }: SearchBarProps) => {
searchBarStyles,
searchBarTextStyles,
searchBarPlaceholderColor,
} = React.useContext(KeyboardContext);
const inputRef = React.useRef<TextInput>(null);
} = React.useContext(KeyboardContext)
const inputRef = React.useRef<TextInput>(null)
const handleSearch = (text: string) => {
setSearchPhrase(text);
};
setSearchPhrase(text)
}
const clearPhrase = () => {
setSearchPhrase('');
inputRef.current?.blur();
setActiveCategoryIndex(0);
flatListRef?.current?.scrollToIndex({ index: 0, animated: true });
};
setSearchPhrase('')
inputRef.current?.blur()
setActiveCategoryIndex(0)
flatListRef?.current?.scrollToIndex({ index: 0, animated: true })
}
return (
<View style={[styles.container, searchBarStyles]}>
@ -57,8 +51,8 @@ export const SearchBar = ({ flatListRef }: SearchBarProps) => {
</TouchableOpacity>
)}
</View>
);
};
)
}
const styles = StyleSheet.create({
container: {
@ -78,4 +72,4 @@ const styles = StyleSheet.create({
button: {
marginRight: 8,
},
});
})

View File

@ -1,28 +1,28 @@
import * as React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import type { JsonEmoji } from '../types';
import * as React from 'react'
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
import type { JsonEmoji } from '../types'
export class SingleEmoji extends React.Component<{
item: JsonEmoji;
onPress: () => void;
emojiSize: number;
item: JsonEmoji
onPress: () => void
emojiSize: number
}> {
shouldComponentUpdate() {
return false;
return false
}
render() {
const { item, emojiSize, onPress } = this.props;
const { item, emojiSize, onPress } = this.props
return (
<TouchableOpacity onPress={onPress} style={styles.container}>
<View style={styles.iconContainer}>
<Text style={{ fontSize: emojiSize }}>{item.emoji}</Text>
</View>
</TouchableOpacity>
);
)
}
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 8 },
iconContainer: { justifyContent: 'center', alignItems: 'center' },
});
})

View File

@ -1,62 +1,52 @@
import * as React from 'react';
import type { TextStyle, ViewStyle } from 'react-native';
import {
defaultKeyboardContext,
defaultKeyboardValues,
} from './KeyboardProvider';
import type {
CategoryTranslation,
EmojiType,
CategoryTypes,
CategoryPosition,
} from '../types';
import * as React from 'react'
import type { TextStyle, ViewStyle } from 'react-native'
import { defaultKeyboardContext, defaultKeyboardValues } from './KeyboardProvider'
import type { CategoryTranslation, EmojiType, CategoryTypes, CategoryPosition } from '../types'
export type OnEmojiSelected = (emoji: EmojiType) => void;
export type OnEmojiSelected = (emoji: EmojiType) => void
export type KeyboardProps = {
open: boolean;
onClose: () => void;
onEmojiSelected: OnEmojiSelected;
emojiSize?: number;
containerStyles?: ViewStyle;
knobStyles?: ViewStyle;
headerStyles?: TextStyle;
expandable?: boolean;
hideHeader?: boolean;
defaultHeight?: number | string;
expandedHeight?: number | string;
backdropColor?: string;
categoryColor?: string;
activeCategoryColor?: string;
categoryContainerColor?: string;
activeCategoryContainerColor?: string;
open: boolean
onClose: () => void
onEmojiSelected: OnEmojiSelected
emojiSize?: number
containerStyles?: ViewStyle
knobStyles?: ViewStyle
headerStyles?: TextStyle
expandable?: boolean
hideHeader?: boolean
defaultHeight?: number | string
expandedHeight?: number | string
backdropColor?: string
categoryColor?: string
activeCategoryColor?: string
categoryContainerColor?: string
activeCategoryContainerColor?: string
onCategoryChangeFailed?: (info: {
index: number;
highestMeasuredFrameIndex: number;
averageItemLength: number;
}) => void;
translation?: CategoryTranslation;
disabledCategory?: CategoryTypes[];
enableRecentlyUsed?: boolean;
categoryPosition?: CategoryPosition;
enableSearchBar?: boolean;
closeSearchColor?: string;
searchBarStyles?: ViewStyle;
searchBarTextStyles?: TextStyle;
searchBarPlaceholderColor?: string;
};
index: number
highestMeasuredFrameIndex: number
averageItemLength: number
}) => void
translation?: CategoryTranslation
disabledCategory?: CategoryTypes[]
enableRecentlyUsed?: boolean
categoryPosition?: CategoryPosition
enableSearchBar?: boolean
closeSearchColor?: string
searchBarStyles?: ViewStyle
searchBarTextStyles?: TextStyle
searchBarPlaceholderColor?: string
}
export type ContextValues = {
activeCategoryIndex: number;
setActiveCategoryIndex: (index: number) => void;
numberOfColumns: number;
width: number;
searchPhrase: string;
setSearchPhrase: (phrase: string) => void;
};
activeCategoryIndex: number
setActiveCategoryIndex: (index: number) => void
numberOfColumns: number
width: number
searchPhrase: string
setSearchPhrase: (phrase: string) => void
}
export const KeyboardContext = React.createContext<
Required<KeyboardProps> & ContextValues
>({
export const KeyboardContext = React.createContext<Required<KeyboardProps> & ContextValues>({
...defaultKeyboardContext,
...defaultKeyboardValues,
});
})

View File

@ -1,18 +1,13 @@
import * as React from 'react';
import { useWindowDimensions } from 'react-native';
import {
KeyboardProps,
ContextValues,
KeyboardContext,
OnEmojiSelected,
} from './KeyboardContext';
import en from '../translation/en';
import type { EmojiType } from '../types';
import * as React from 'react'
import { useWindowDimensions } from 'react-native'
import { KeyboardProps, ContextValues, KeyboardContext, OnEmojiSelected } from './KeyboardContext'
import en from '../translation/en'
import type { EmojiType } from '../types'
type ProviderProps = Partial<KeyboardProps> & {
children: React.ReactNode;
onEmojiSelected: OnEmojiSelected;
};
children: React.ReactNode
onEmojiSelected: OnEmojiSelected
}
export const defaultKeyboardContext: Required<KeyboardProps> = {
open: false,
@ -32,7 +27,7 @@ export const defaultKeyboardContext: Required<KeyboardProps> = {
categoryContainerColor: '#e3dbcd',
activeCategoryContainerColor: '#ffffff',
onCategoryChangeFailed: (info) => {
console.warn(info);
console.warn(info)
},
translation: en,
disabledCategory: [],
@ -43,7 +38,7 @@ export const defaultKeyboardContext: Required<KeyboardProps> = {
searchBarStyles: {},
searchBarTextStyles: {},
searchBarPlaceholderColor: '#00000055',
};
}
export const defaultKeyboardValues: ContextValues = {
activeCategoryIndex: 0,
@ -52,25 +47,19 @@ export const defaultKeyboardValues: ContextValues = {
width: 0,
searchPhrase: '',
setSearchPhrase: (_phrase: string) => {},
};
}
export const KeyboardProvider: React.FC<ProviderProps> = React.memo((props) => {
const { width } = useWindowDimensions();
const [activeCategoryIndex, setActiveCategoryIndex] = React.useState(0);
const [searchPhrase, setSearchPhrase] = React.useState('');
const { width } = useWindowDimensions()
const [activeCategoryIndex, setActiveCategoryIndex] = React.useState(0)
const [searchPhrase, setSearchPhrase] = React.useState('')
const numberOfColumns = React.useRef<number>(
Math.floor(
width /
((props.emojiSize
? props.emojiSize
: defaultKeyboardContext.emojiSize) *
2)
)
);
Math.floor(width / ((props.emojiSize ? props.emojiSize : defaultKeyboardContext.emojiSize) * 2))
)
React.useEffect(() => {
if (props.open) setActiveCategoryIndex(0);
setSearchPhrase('');
}, [props.open]);
if (props.open) setActiveCategoryIndex(0)
setSearchPhrase('')
}, [props.open])
const value: Required<KeyboardProps> & ContextValues = {
...defaultKeyboardContext,
@ -82,12 +71,8 @@ export const KeyboardProvider: React.FC<ProviderProps> = React.memo((props) => {
width,
searchPhrase,
setSearchPhrase,
};
return (
<KeyboardContext.Provider value={value}>
{props.children}
</KeyboardContext.Provider>
);
});
}
return <KeyboardContext.Provider value={value}>{props.children}</KeyboardContext.Provider>
})
KeyboardProvider.displayName = 'KeyboardProvider';
KeyboardProvider.displayName = 'KeyboardProvider'

View File

@ -1,19 +1,17 @@
import { MutableRefObject, useCallback, useEffect, useRef } from 'react';
import { MutableRefObject, useCallback, useEffect, useRef } from 'react'
export const useTimeout = () => {
const timeoutRef = useRef(null) as MutableRefObject<ReturnType<
typeof setTimeout
> | null>;
const timeoutRef = useRef(null) as MutableRefObject<ReturnType<typeof setTimeout> | null>
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
clearTimeout(timeoutRef.current)
}
};
}, []);
}
}, [])
return useCallback((callback: () => void, time: number) => {
timeoutRef.current = setTimeout(callback, time);
}, []);
};
timeoutRef.current = setTimeout(callback, time)
}, [])
}

View File

@ -1,9 +1,9 @@
import { EmojiPicker } from './EmojiPicker';
import { EmojiKeyboard } from './EmojiKeyboard';
import en from './translation/en';
import pl from './translation/pl';
import { EmojiPicker } from './EmojiPicker'
import { EmojiKeyboard } from './EmojiKeyboard'
import en from './translation/en'
import pl from './translation/pl'
export { EmojiKeyboard };
export { en, pl };
export { EmojiKeyboard }
export { en, pl }
export default EmojiPicker;
export default EmojiPicker

View File

@ -1,13 +1,13 @@
import type { JsonEmoji } from 'src/types';
import type { JsonEmoji } from 'src/types'
export type RecentEmojiState = {
recentlyUsed: JsonEmoji[];
};
recentlyUsed: JsonEmoji[]
}
export type RecentEmojiAction =
| { type: 'RECENT_EMOJI_ADD'; payload: JsonEmoji }
| { type: 'RECENT_EMOJI_REMOVE'; payload: JsonEmoji }
| { type: 'RECENT_EMOJI_CLEAR' };
| { type: 'RECENT_EMOJI_CLEAR' }
export default function recentEmojiReducer(
state: RecentEmojiState,
@ -18,18 +18,18 @@ export default function recentEmojiReducer(
return {
...state,
recentlyUsed: [action.payload, ...filterEmoji(state, action.payload)],
};
}
case 'RECENT_EMOJI_REMOVE':
return {
...state,
recentlyUsed: filterEmoji(state, action.payload),
};
}
case 'RECENT_EMOJI_CLEAR':
return { ...state, recentlyUsed: [] };
return { ...state, recentlyUsed: [] }
default:
return state;
return state
}
}
const filterEmoji = (state: RecentEmojiState, emoji: JsonEmoji) =>
state.recentlyUsed.filter((usedEmoji) => usedEmoji.emoji !== emoji.emoji);
state.recentlyUsed.filter((usedEmoji) => usedEmoji.emoji !== emoji.emoji)

View File

@ -1,11 +1,8 @@
import recentEmojiReducer, {
RecentEmojiAction,
RecentEmojiState,
} from './RecentEmojiReducer';
import recentEmojiReducer, { RecentEmojiAction, RecentEmojiState } from './RecentEmojiReducer'
// TODO:
// - combine Keyboard reducers in future
export type KeyboardState = RecentEmojiState;
export type KeyboardAction = RecentEmojiAction;
export default recentEmojiReducer;
export type KeyboardState = RecentEmojiState
export type KeyboardAction = RecentEmojiAction
export default recentEmojiReducer

View File

@ -1,29 +1,29 @@
import { useEffect, useState } from 'react';
import type { KeyboardAction, KeyboardState } from './reducers';
import keyboardReducer from './reducers';
import { useEffect, useState } from 'react'
import type { KeyboardAction, KeyboardState } from './reducers'
import keyboardReducer from './reducers'
let globalKeyboardState: KeyboardState = {
recentlyUsed: [],
};
}
type KeyboardStateSetter = () => any;
const keyboardStateListeners = new Set<KeyboardStateSetter>();
type KeyboardStateSetter = () => any
const keyboardStateListeners = new Set<KeyboardStateSetter>()
const setKeyboardState = (action: KeyboardAction) => {
globalKeyboardState = keyboardReducer(globalKeyboardState, action);
keyboardStateListeners.forEach((listener) => listener());
};
globalKeyboardState = keyboardReducer(globalKeyboardState, action)
keyboardStateListeners.forEach((listener) => listener())
}
export const useKeyboardStore = () => {
const [keyboardState, setState] = useState(globalKeyboardState);
const [keyboardState, setState] = useState(globalKeyboardState)
useEffect(() => {
const listener = () => setState(globalKeyboardState);
keyboardStateListeners.add(listener);
const listener = () => setState(globalKeyboardState)
keyboardStateListeners.add(listener)
return () => {
keyboardStateListeners.delete(listener);
};
}, [keyboardState]);
keyboardStateListeners.delete(listener)
}
}, [keyboardState])
return { keyboardState, setKeyboardState };
};
return { keyboardState, setKeyboardState }
}

View File

@ -1,4 +1,4 @@
import type { CategoryTranslation } from '../types';
import type { CategoryTranslation } from '../types'
export const en: CategoryTranslation = {
recently_used: 'Recently used',
@ -12,5 +12,5 @@ export const en: CategoryTranslation = {
symbols: 'Symbols',
flags: 'Flags',
search: 'Search',
};
export default en;
}
export default en

View File

@ -1,4 +1,4 @@
import type { CategoryTranslation } from '../types';
import type { CategoryTranslation } from '../types'
const pl: CategoryTranslation = {
recently_used: 'Ostatnio używane',
@ -12,5 +12,5 @@ const pl: CategoryTranslation = {
symbols: 'Symbole',
flags: 'Flagi',
search: 'Szukaj',
};
export default pl;
}
export default pl

View File

@ -10,39 +10,39 @@ export const CATEGORIES_NAVIGATION = [
{ icon: 'Flag', category: 'flags' },
{ icon: 'Clock', category: 'recently_used' },
{ icon: 'Search', category: 'search' },
] as const;
] as const
export type IconNames = typeof CATEGORIES_NAVIGATION[number]['icon'];
export type CategoryTypes = typeof CATEGORIES_NAVIGATION[number]['category'];
export type IconNames = typeof CATEGORIES_NAVIGATION[number]['icon']
export type CategoryTypes = typeof CATEGORIES_NAVIGATION[number]['category']
export const CATEGORIES: readonly CategoryTypes[] = CATEGORIES_NAVIGATION.map(
({ category }) => category
);
)
export type JsonEmoji = {
emoji: string;
name: string;
v: string;
};
emoji: string
name: string
v: string
}
export type EmojiType = {
emoji: string;
name: string;
slug: string;
unicode_version: string;
};
emoji: string
name: string
slug: string
unicode_version: string
}
export type CategoryPosition = 'floating' | 'top' | 'bottom';
export type CategoryPosition = 'floating' | 'top' | 'bottom'
export type CategoryNavigationItem = {
icon: IconNames;
category: CategoryTypes;
};
icon: IconNames
category: CategoryTypes
}
export type CategoryTranslation = {
[key in CategoryTypes]: string;
};
[key in CategoryTypes]: string
}
export type EmojisByCategory = {
title: CategoryTypes;
data: EmojiType[];
};
title: CategoryTypes
data: EmojiType[]
}

View File

@ -1,29 +1,22 @@
import { CATEGORIES, CategoryTypes, JsonEmoji } from './types';
import { CATEGORIES, CategoryTypes, JsonEmoji } from './types'
export const getHeight = (value: string | number, screenHeight: number) =>
typeof value === 'number'
? value
: (screenHeight / 100) * parseInt(value.replace('%', ''), 10);
typeof value === 'number' ? value : (screenHeight / 100) * parseInt(value.replace('%', ''), 10)
export const exhaustiveTypeCheck = (arg: never, strict = true) => {
console.log(`unhandled union case for : ${arg}`);
console.log(`unhandled union case for : ${arg}`)
if (strict) {
throw new Error(`unhandled union case for : ${arg}`);
throw new Error(`unhandled union case for : ${arg}`)
}
};
}
export const parseEmoji = (emoji: JsonEmoji) => ({
name: emoji.name,
emoji: emoji.emoji,
unicode_version: emoji.v,
slug: emoji.name.replace(' ', '_'),
});
})
export const getCategoryIndex = (
disabledCategory: CategoryTypes[],
category: CategoryTypes
) => ({
index: CATEGORIES.filter((name) => !disabledCategory.includes(name)).indexOf(
category
),
});
export const getCategoryIndex = (disabledCategory: CategoryTypes[], category: CategoryTypes) => ({
index: CATEGORIES.filter((name) => !disabledCategory.includes(name)).indexOf(category),
})

View File

@ -1,5 +1,4 @@
{
"extends": "./tsconfig",
"exclude": ["example"]
}
}

View File

@ -1837,6 +1837,11 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
"@twgdev/prettier-config@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@twgdev/prettier-config/-/prettier-config-1.0.2.tgz#5a313df4341efb2221b5e7b4c52153e86861b1dc"
integrity sha512-79UJ8Cp+dIoE8V5g8y2SDvshhGQsGaDkTdY3YVbbMzTUW/Bdv/0AOFASNNGKXy7pfkcukeUD27cgRECAU4Swyg==
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
version "7.1.14"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402"