import { styled } from '@uhg-abyss/mobile';Properties
styled( nativeElement: string | React.FC, config?: object)Object Syntax Only
Write using the JavaScript object style syntax. The reasons for this are: performance, bundle size, and developer experience.
const Button = styled('Pressable', { backgroundColor: '$semantic.color.surface.container.emphasis.4', borderColor: '$core.color.brand.100', borderWidth: 2, borderRadius: 24, padding: 12,});Prop Interpolation vs Variants
You can conditionally apply variants at the consumption level.
const Button = styled('Pressable', { ... variants: { isDisabled: { true: { backgroundColor: '$semantic.color.surface.interactive.standards.disabled.secondary' }, }, },});Tokens and Themes
You can define tokens in the config file and seamlessly consume and access directly in the Style Object.
const Button = styled('Pressable', { ... backgroundColor: '$semantic.color.surface.container.primary', paddingVertical: '$semantic.spacing.sm', paddingHorizontal: '$semantic.spacing.lg',});Responsive Media Queries
Use standard @media queries with min-width, max-width, and orientation to create responsive layouts. Any valid CSS media query is supported. The following are recommended baseline breakpoints for common phone and tablet form factors:
| Query | Matches |
|---|---|
@media (max-width: 479px) | Phone portrait |
@media (min-width: 480px) | Phone landscape + tablet portrait |
@media (min-width: 480px) and (orientation: landscape) | Phone landscape + tablet landscape |
@media (min-width: 768px) and (orientation: portrait) | Tablet portrait |
@media (min-width: 768px) and (orientation: landscape) | Tablet landscape - overrides above tablet landscape |
const Card = styled('View', { flexDirection: 'column',
// phone landscape + tablet portrait '@media (min-width: 480px)': { flexDirection: 'row', padding: '$semantic.spacing.lg', },
// tablet landscape '@media (min-width: 768px) and (orientation: landscape)': { padding: '$semantic.spacing.xxl', },});Animations
You can use Animated within a styled component to add animations. Animation values must be passed to the component's style prop, not placed within the styled configs.
import { Animated } from 'react-native';
const AnimatedButton = styled(Animated.View, { alignItems: 'center', borderRadius: 24, paddingVertical: '$semantic.spacing.sm', paddingHorizontal: '$semantic.spacing.lg', backgroundColor: '$semantic.color.surface.container.primary', });
const animatedValue = useRef(new Animated.Value(1)).current;
const fade = (direction) => { Animated.timing(animatedValue, { toValue: direction === 'in' ? 0.95 : 1, duration: direction === 'in' ? 100 : 300, useNativeDriver: true, easing: Easing.bezier(0.25, 0.1, 0.25, 0.1), }).start();};
const handlePressIn = (e) => { fade('in');};
const handlePressOut = (e) => { fade('out');};
<AnimatedButton style={{ transform: [{ scale: animatedValue }] }}>Dynamic/Static
When static variants won't work and you need a variable style, you can use the props config in the styled tool. Place all of your styles along with variants in the static config. The props config takes in a function with the props passed into the component as the function's parameters. You can then use those props to handle dynamic styles like sizing and colors. The function should return the style properties to add to the component. The props function overrides static styles and styles defined in variants.
For the best results and performance, it is recommended to use variants when possible.