Primitives

All primitives accept BoxStyleProps for layout and spacing. Props resolve through resolveBoxStyle which maps shorthand tokens to React Native style objects.

BoxStyleProps reference

PropMaps toToken type
bgbackgroundColorColorTokens key or raw string
p / px / py / pt / pb / pl / prpadding*SpacingTokens key or number
m / mx / my / mt / mb / ml / mrmargin*SpacingTokens key or number
roundedborderRadiusRadiiTokens key or number
shadowshadow properties + elevationShadowTokens key
flexflexnumber
rowflexDirection: 'row'boolean
centeralignItems + justifyContent: 'center'boolean
w / hwidth / heightnumber or string
borderWidth / borderColorborderWidth / borderColornumber / ColorProp
opacityopacitynumber
overflowoverflow'visible' | 'hidden' | 'scroll'
position / top / bottom / left / right / zIndexdirect RN style fieldsnumber

Box

The base layout primitive. Every other component is built on top of it.

PropTypeDefaultDescription
style?ViewStyleAdditional raw RN styles, merged last
accessibilityRole?AccessibilityRoleARIA role
accessibilityLabel?stringScreen reader label
testID?stringTest selector
BoxStylePropsAll 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.

PropTypeDefaultDescription
variant?'display' | 'heading' | 'body' | 'caption' | 'label''body'Preset style combination
size?SpacingPropOverride font size
weight?'regular' | 'medium' | 'semibold' | 'bold'Override font weight
family?'display' | 'body' | 'mono'Override font family
color?ColorPropforegroundText color
align?'left' | 'center' | 'right' | 'justify'Text alignment
lineHeight?'tight' | 'normal' | 'relaxed'Line height
letterSpacing?numberLetter 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.

PropTypeDefaultDescription
onPress?() => voidPress handler
disabled?booleanfalseDisables interaction; reduces opacity
loading?booleanfalseImplies disabled; shows loading state
haptic?booleantrueFire selection haptic on press
scaleOnPress?number0.97Scale factor during press
BoxStylePropsAll 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.

PropTypeDefaultDescription
srcstring | numberURL string or require() asset
alt?stringAccessibility label
resizeMode?'cover' | 'contain' | 'stretch' | 'center''cover'Resize strategy
aspectRatio?numberForces width/height ratio
loadingIndicatorColor?stringActivity indicator tint while loading
BoxStylePropsAll 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.

PropTypeDefaultDescription
namestringIcon key within the registered set
size?SpacingProp'md' (16px)Icon size
color?ColorPropIcon 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.

PropTypeDefaultDescription
size?SpacingPropFixed 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.

PropTypeDefaultDescription
orientation?'horizontal' | 'vertical''horizontal'Line direction
thickness?number1Line width/height in pixels
color?ColorPropborderLine color
spacing?SpacingPropMargin 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.

PropTypeDefaultDescription
widthnumber | stringPlaceholder width
heightnumberPlaceholder height
rounded?RadiiProp'sm'Corner radius
circle?booleanfalseOverrides rounded to 'full'
speed?number1000Animation 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.

PropTypeDefaultDescription
colorsstring[]Gradient color stops
direction?'horizontal' | 'vertical' | 'diagonal''vertical'Gradient axis
locations?number[]Position (0-1) for each color stop
BoxStylePropsAll 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.

PropTypeDefaultDescription
intensity?number50Blur strength (0–100, clamped)
tint?'default' | 'light' | 'dark''default'Background tint
BoxStylePropsAll 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.

PropTypeDefaultDescription
labelstringButton text
onPress?() => voidPress handler
variant?'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive''primary'Visual style
size?'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Height and padding scale
disabled?booleanfalseDisables interaction; reduces opacity
loading?booleanfalseReplaces label with a spinner; implies disabled
iconLeft?stringRegistered icon name rendered to the left of the label
iconRight?stringRegistered icon name rendered to the right of the label
fullWidth?booleanfalseStretch the button to fill its container
accessibilityLabel?stringAccessibility label (defaults to label)
testID?stringTest 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.

PropTypeDefaultDescription
iconstringRegistered icon name
onPress?() => voidPress handler
variant?'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive''ghost'Visual style
size?'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Button diameter
disabled?booleanfalseDisables interaction; reduces opacity
loading?booleanfalseReplaces icon with a spinner
rounded?'sm' | 'md' | 'lg' | 'full''md'Corner radius
accessibilityLabelstringRequired screen reader label
testID?stringTest 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}
/>

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.

PropTypeDefaultDescription
labelstringLink text
href?stringURL to open via Linking.openURL when tapped
onPress?() => voidIn-app navigation callback (takes precedence over href)
variant?'body' | 'caption' | 'label''body'Typography variant
color?ColorProp'primary'Link color
underline?booleantrueUnderline the link text
external?booleanfalseAppend an external-link icon after the label
disabled?booleanfalseDisables interaction
accessibilityLabel?stringAccessibility label (defaults to label)
testID?stringTest 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"
/>