Text
Slot primitive
Types primitive
Demo
Styled text component and inheritance system.
Installation
npx @react-native-reusables/cli@latest add text
Copy/paste the following code to ~/components/ui/text.tsx
:
import * as Slot from '@rn-primitives/slot';import type { SlottableTextProps, TextRef } from '@rn-primitives/types';import * as React from 'react';import { Text as RNText } from 'react-native';import { cn } from '~/lib/utils';
const TextClassContext = React.createContext<string | undefined>(undefined);
const Text = React.forwardRef<TextRef, SlottableTextProps>( ({ className, asChild = false, ...props }, ref) => { const textClass = React.useContext(TextClassContext); const Component = asChild ? Slot.Text : RNText; return ( <Component className={cn('text-base text-foreground web:select-text', textClass, className)} ref={ref} {...props} /> ); });Text.displayName = 'Text';
export { Text, TextClassContext };
Props
Accepts all the props of the React-Native Text
component.
Usage
Uses the inheritance system to apply styles from parent components. Usage is the same as the React-Native Text
component.
Inheritance system
By default, children cannot inherit styles from their parent components in React-Native. This can be problematic
for components like a Button
with variants where its Text
component should change its styles based on the variant.
To solve this, components that need to pass styles to their Text
children are wrapped with a TextClassContext.Provider
.
The Text
component applies the styles from the TextClassContext
to the React-Native Text
component.
Specificity
The algorithm used to determine which styles to apply is based on the following order of specificity:
Order of specificity:
- The added
className
of theText
component when being used - The
value
of the closestTextClassContext.Provider
to childrenText
components - The default
className
in theText
component
Example:
import { Text } from '~/components/ui/text'; import { Parent } from './Parent'; import { OtherParent } from './OtherParent';
function Screen(){ return ( <> {/* Default behavior without a parent `TextClassContext.Provider` */} <Text>The applied className is foreground</Text> <Parent> {/* Inherits the `TextClassContext.Provider` value from the `Parent` component and overrides the default `Text` component `className` */} <Text>The applied className is text-red-500</Text> {/* This `className` will override the `TextClassContext.Provider` value */} <Text className="text-blue-500">The applied className is text-blue-500</Text> <OtherParent> {/* Inherits the `TextClassContext.Provider` value from the `OtherParent` component overrides the `TextClassContext.Provider` value from the `Parent` */} <Text>The applied className is text-purple-500</Text> </OtherParent> </Parent> </> ) }
import { TextClassContext } from '~/components/ui/text';
export function Parent({ children }) { return ( <TextClassContext.Provider value="text-red-500"> <View> {children} </View> </TextClassContext.Provider> ) }
import { TextClassContext } from '~/components/ui/text';
export function OtherParent({ children }) { return ( <TextClassContext.Provider value="text-purple-500"> <View> {children} </View> </TextClassContext.Provider> ) }