Primitives
All primitives accept BoxStyleProps for layout and spacing. Props resolve through resolveBoxStyle which maps shorthand tokens to React Native style objects.
BoxStyleProps reference
| Prop | Maps to | Token type |
|---|---|---|
bg | backgroundColor | ColorTokens key or raw string |
p / px / py / pt / pb / pl / pr | padding* | SpacingTokens key or number |
m / mx / my / mt / mb / ml / mr | margin* | SpacingTokens key or number |
rounded | borderRadius | RadiiTokens key or number |
shadow | shadow properties + elevation | ShadowTokens key |
flex | flex | number |
row | flexDirection: 'row' | boolean |
center | alignItems + justifyContent: 'center' | boolean |
w / h | width / height | number or string |
borderWidth / borderColor | borderWidth / borderColor | number / ColorProp |
opacity | opacity | number |
overflow | overflow | 'visible' | 'hidden' | 'scroll' |
position / top / bottom / left / right / zIndex | direct RN style fields | number |
Box
The base layout primitive. Every other component is built on top of it.
| Prop | Type | Default | Description |
|---|---|---|---|
style? | ViewStyle | — | Additional raw RN styles, merged last |
accessibilityRole? | AccessibilityRole | — | ARIA role |
accessibilityLabel? | string | — | Screen reader label |
testID? | string | — | Test selector |
…BoxStyleProps | — | — | All shorthand layout props |
import { Box } from '@objectifthunes/limestone-sdk';
function Card() {
return (
<Box bg="card" rounded="lg" shadow="md" p="lg">
{/* content */}
</Box>
);
}
Text
Token-based typography. variant sets sensible defaults; individual props override them.
| Prop | Type | Default | Description |
|---|---|---|---|
variant? | 'display' | 'heading' | 'body' | 'caption' | 'label' | 'body' | Preset style combination |
size? | SpacingProp | — | Override font size |
weight? | 'regular' | 'medium' | 'semibold' | 'bold' | — | Override font weight |
family? | 'display' | 'body' | 'mono' | — | Override font family |
color? | ColorProp | foreground | Text color |
align? | 'left' | 'center' | 'right' | 'justify' | — | Text alignment |
lineHeight? | 'tight' | 'normal' | 'relaxed' | — | Line height |
letterSpacing? | number | — | Letter spacing |
textDecorationLine? | TextStyle['textDecorationLine'] | — | Underline, line-through, etc. |
textTransform? | TextStyle['textTransform'] | — | uppercase, lowercase, capitalize |
import { Text } from '@objectifthunes/limestone-sdk';
function Article() {
return (
<>
<Text variant="heading" weight="bold">Getting Started</Text>
<Text variant="body" color="mutedForeground">
Read the full guide below.
</Text>
<Text variant="caption" align="center">Last updated today</Text>
</>
);
}
Pressable
An interactive wrapper with haptic feedback and press scaling built in.
| Prop | Type | Default | Description |
|---|---|---|---|
onPress? | () => void | — | Press handler |
disabled? | boolean | false | Disables interaction; reduces opacity |
loading? | boolean | false | Implies disabled; shows loading state |
haptic? | boolean | true | Fire selection haptic on press |
scaleOnPress? | number | 0.97 | Scale factor during press |
…BoxStyleProps | — | — | All shorthand layout props |
import { Pressable, Text } from '@objectifthunes/limestone-sdk';
function SubmitButton({ onPress, loading }: { onPress: () => void; loading: boolean }) {
return (
<Pressable
onPress={onPress}
loading={loading}
bg="primary"
rounded="md"
px="xl"
py="md"
center
>
<Text color="primaryForeground" weight="semibold">Submit</Text>
</Pressable>
);
}
Image
Renders a network or bundled image with optional aspect ratio and loading indicator.
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | number | — | URL string or require() asset |
alt? | string | — | Accessibility label |
resizeMode? | 'cover' | 'contain' | 'stretch' | 'center' | 'cover' | Resize strategy |
aspectRatio? | number | — | Forces width/height ratio |
loadingIndicatorColor? | string | — | Activity indicator tint while loading |
…BoxStyleProps | — | — | All shorthand layout props |
import { Image } from '@objectifthunes/limestone-sdk';
function Avatar({ uri }: { uri: string }) {
return (
<Image
src={uri}
alt="User avatar"
w={64}
h={64}
rounded="full"
resizeMode="cover"
/>
);
}
Icon
Renders an SVG icon by name from a registered icon set. Register at least one set before rendering any icon.
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | — | Icon key within the registered set |
size? | SpacingProp | 'md' (16px) | Icon size |
color? | ColorProp | — | Icon fill color |
Registering an icon set
import { registerIconSet, clearIconRegistry } from '@objectifthunes/limestone-sdk';
registerIconSet('material', {
home: { viewBox: '0 0 24 24', path: 'M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z' },
search: { viewBox: '0 0 24 24', path: 'M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5...' },
close: { viewBox: '0 0 24 24', path: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41...' },
});
clearIconRegistry() removes all registered sets. Use it in test teardown.
import { Icon } from '@objectifthunes/limestone-sdk';
function NavItem() {
return <Icon name="home" size="lg" color="primary" />;
}
Spacer
Inserts empty space. Without size it expands to fill available flex space (flex: 1). With size it renders a fixed gap.
| Prop | Type | Default | Description |
|---|---|---|---|
size? | SpacingProp | — | Fixed height (vertical) or width (horizontal) |
direction? | 'vertical' | 'horizontal' | 'vertical' | Axis of spacing |
import { Stack, Text, Spacer } from '@objectifthunes/limestone-sdk';
function Toolbar() {
return (
<Stack direction="horizontal" p="md">
<Text variant="heading">Title</Text>
<Spacer />
<Icon name="close" />
</Stack>
);
}
Divider
A single-pixel line between content sections.
| Prop | Type | Default | Description |
|---|---|---|---|
orientation? | 'horizontal' | 'vertical' | 'horizontal' | Line direction |
thickness? | number | 1 | Line width/height in pixels |
color? | ColorProp | border | Line color |
spacing? | SpacingProp | — | Margin on each side of the divider |
import { Stack, Text, Divider } from '@objectifthunes/limestone-sdk';
function Section() {
return (
<Stack gap="md">
<Text variant="body">First paragraph</Text>
<Divider color="border" spacing="sm" />
<Text variant="body">Second paragraph</Text>
</Stack>
);
}
Skeleton
A placeholder shape for loading states. The consumer drives the animation using the returned animationDuration.
| Prop | Type | Default | Description |
|---|---|---|---|
width | number | string | — | Placeholder width |
height | number | — | Placeholder height |
rounded? | RadiiProp | 'sm' | Corner radius |
circle? | boolean | false | Overrides rounded to 'full' |
speed? | number | 1000 | Animation duration in ms |
import { Stack, Skeleton } from '@objectifthunes/limestone-sdk';
function ProfileSkeleton() {
return (
<Stack direction="horizontal" gap="md" p="lg">
<Skeleton width={48} height={48} circle />
<Stack gap="sm" flex={1}>
<Skeleton width="60%" height={16} />
<Skeleton width="40%" height={14} />
</Stack>
</Stack>
);
}
Gradient
A linear gradient container. Requires the expo-linear-gradient peer dependency.
| Prop | Type | Default | Description |
|---|---|---|---|
colors | string[] | — | Gradient color stops |
direction? | 'horizontal' | 'vertical' | 'diagonal' | 'vertical' | Gradient axis |
locations? | number[] | — | Position (0-1) for each color stop |
…BoxStyleProps | — | — | All shorthand layout props |
import { Gradient, Text } from '@objectifthunes/limestone-sdk';
function HeroBanner() {
return (
<Gradient
colors={['#6366F1', '#8B5CF6']}
direction="diagonal"
p="2xl"
rounded="xl"
>
<Text color="primaryForeground" variant="heading">Welcome</Text>
</Gradient>
);
}
BlurView
A frosted-glass effect. Requires the expo-blur peer dependency.
| Prop | Type | Default | Description |
|---|---|---|---|
intensity? | number | 50 | Blur strength (0–100, clamped) |
tint? | 'default' | 'light' | 'dark' | 'default' | Background tint |
…BoxStyleProps | — | — | All shorthand layout props |
import { BlurView, Text } from '@objectifthunes/limestone-sdk';
function FloatingCard() {
return (
<BlurView intensity={80} tint="dark" rounded="lg" p="lg">
<Text color="primaryForeground">Blurred background panel</Text>
</BlurView>
);
}
Button
A styled, accessible button with label, icon, loading, and disabled states. Built on top of Pressable with preset size and variant tokens.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Button text |
onPress? | () => void | — | Press handler |
variant? | 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'primary' | Visual style |
size? | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Height and padding scale |
disabled? | boolean | false | Disables interaction; reduces opacity |
loading? | boolean | false | Replaces label with a spinner; implies disabled |
iconLeft? | string | — | Registered icon name rendered to the left of the label |
iconRight? | string | — | Registered icon name rendered to the right of the label |
fullWidth? | boolean | false | Stretch the button to fill its container |
accessibilityLabel? | string | — | Accessibility label (defaults to label) |
testID? | string | — | Test identifier |
import { Button } from '@objectifthunes/limestone-sdk';
// Primary action
<Button label="Save changes" onPress={save} />
// Destructive with loading state
<Button
label="Delete account"
variant="destructive"
loading={isDeleting}
onPress={deleteAccount}
/>
// Ghost with icon
<Button
label="Share"
variant="ghost"
iconLeft="share"
onPress={share}
/>
// Full-width outline
<Button
label="Sign in with Google"
variant="outline"
iconLeft="google"
fullWidth
onPress={signInGoogle}
/>
IconButton
A square/circular icon-only button. Semantically equivalent to Button but renders no label — use accessibilityLabel for screen readers.
| Prop | Type | Default | Description |
|---|---|---|---|
icon | string | — | Registered icon name |
onPress? | () => void | — | Press handler |
variant? | 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'ghost' | Visual style |
size? | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Button diameter |
disabled? | boolean | false | Disables interaction; reduces opacity |
loading? | boolean | false | Replaces icon with a spinner |
rounded? | 'sm' | 'md' | 'lg' | 'full' | 'md' | Corner radius |
accessibilityLabel | string | — | Required screen reader label |
testID? | string | — | Test identifier |
import { IconButton } from '@objectifthunes/limestone-sdk';
// Close button
<IconButton
icon="x"
variant="ghost"
accessibilityLabel="Close dialog"
onPress={closeDialog}
/>
// Round primary action
<IconButton
icon="plus"
variant="primary"
size="lg"
rounded="full"
accessibilityLabel="Add item"
onPress={addItem}
/>
Link
An inline or block text link. Renders as a Pressable with typography and color styled to the theme’s link tokens. Supports external URL opening and in-app navigation callbacks.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Link text |
href? | string | — | URL to open via Linking.openURL when tapped |
onPress? | () => void | — | In-app navigation callback (takes precedence over href) |
variant? | 'body' | 'caption' | 'label' | 'body' | Typography variant |
color? | ColorProp | 'primary' | Link color |
underline? | boolean | true | Underline the link text |
external? | boolean | false | Append an external-link icon after the label |
disabled? | boolean | false | Disables interaction |
accessibilityLabel? | string | — | Accessibility label (defaults to label) |
testID? | string | — | Test identifier |
import { Link, Text, Stack } from '@objectifthunes/limestone-sdk';
// In-app navigation
function SignupPrompt() {
return (
<Stack direction="horizontal" gap="xs">
<Text variant="body" color="mutedForeground">Already have an account?</Text>
<Link label="Sign in" onPress={() => router.push('/login')} />
</Stack>
);
}
// External URL
<Link
label="Privacy Policy"
href="https://example.com/privacy"
external
variant="caption"
color="mutedForeground"
/>