-
I'm working on a button for the navigation bar in an expo universal app (web + mobile). How can I write ProjectIonicons in a way that allows me to maintain the proper styling and theming of ScopedThemes while also avoiding writing a uniprops callback every time I want to add a new icon? And yes, I can write this easier with theme, but that would make my entire component re-render and would force me to also do 2-3 layers of wrappers and memoization for a simple text icon :)) Ideally I would just want to write color=color and size=size import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import { withUnistyles } from 'react-native-unistyles';
export const IoniconsSizes = {
field: 16,
cell: 20,
toolbar: 24,
button: 28,
};
const ProjectIonicons = withUnistyles(Ionicons);
export type IoniconsName = React.ComponentProps<typeof ProjectIonicons>['name'];
export default ProjectIonicons;
import React, { useCallback, useMemo } from 'react';
import { Text, View } from 'react-native';
import { StyleSheet } from 'react-native-unistyles';
import ProjectIonicons, { IoniconsName } from '../assets/ProjectIonicons';
import { NavigationBarButtonType } from './types';
const getIoniconsType = (type: string): IoniconsName | string | undefined => {
if (type.startsWith('ionicons-')) {
return type.replace('ionicons-', '');
}
switch (type) {
case 'back':
return 'chevron-back';
case 'settings':
return 'settings-outline';
case 'playground':
return 'hammer-outline';
case 'style':
return 'color-palette-outline';
case 'add':
return 'add-outline';
default:
return undefined;
}
};
const ProjectNavButtonItem = ({
type,
offset,
isRight,
}: {
type: NavigationBarButtonType | string;
offset?: number;
isRight?: boolean;
}) => {
const normalizedOffset = offset && offset !== 0 ? offset : 0;
const uniProps = useCallback((theme: any, rt: any) => {
return {
color: theme.navigationBar.buttonIconStyle.color,
size: theme.navigationBar.buttonIconStyle.fontSize,
};
}, []);
const ioniconsType = useMemo(() => {
return getIoniconsType(type);
}, [type]);
return (
<View style={styles.container(normalizedOffset, isRight)}>
{ioniconsType && ioniconsType?.length > 0 ? (
<ProjectIonicons uniProps={uniProps} style={styles.offsetForIcon(0, isRight)} name={ioniconsType as any} />
) : (
<Text numberOfLines={1} style={styles.text}>
{type}
</Text>
)}
</View>
);
};
export default ProjectNavButtonItem;
const styles = StyleSheet.create((theme) => ({
container: (offset: number, isRight) => ({
...(isRight ? { marginRight: offset } : { marginLeft: offset }),
}),
offsetForIcon: (offset?: number, isRight?: boolean) => ({
...(isRight ? { marginRight: offset ?? 0 } : { marginLeft: offset ?? 0 }),
}),
text: {
...theme.navigationBar.buttonTextStyle,
},
})); @jpudysz any thoughts on this? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
I've tried a few times to simplify the interface by using the style object passed to set the props on Ionicons, but I broke the ScopedTheme, and it started updating when it shouldn't again :) |
Beta Was this translation helpful? Give feedback.
-
I would write my wrapper that passes Something like here: #590 (comment) |
Beta Was this translation helpful? Give feedback.
-
So no way to use uniprops then :( |
Beta Was this translation helpful? Give feedback.
-
You can use uniprops I guess, we introduced few patterns so you can choose freely |
Beta Was this translation helpful? Give feedback.
You can use uniprops I guess, we introduced few patterns so you can choose freely