Feedback
Toast
An imperative notification system. Call toast.* anywhere in your app — no component state required.
Setup
Place ToastContainer once at your app root:
import { ToastContainer } from '@objectifthunes/limestone-sdk';
export default function App() {
return (
<LimestoneProvider config={config}>
<RootNavigator />
<ToastContainer position="top" />
</LimestoneProvider>
);
}
Imperative API
import { toast } from '@objectifthunes/limestone-sdk';
// Variants
toast.success('Changes saved!');
toast.error('Something went wrong.');
toast.warning('Low disk space.');
toast.info('A new version is available.');
// Dismiss by id
const id = toast.success('Processing…');
toast.dismiss(id);
// Clear all toasts
toast.clear();
Alert
A modal alert dialog with configurable actions.
| Prop | Type | Default | Description |
|---|---|---|---|
visible | boolean | — | Controls visibility |
title | string | — | Alert heading |
message? | string | — | Body text |
actions | AlertAction[] | — | Array of buttons |
size? | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Dialog width |
icon? | React.ReactElement | — | Icon rendered above the title |
Each AlertAction is { label: string; onPress: () => void; style?: 'default' | 'cancel' | 'destructive' }.
import { Alert } from '@objectifthunes/limestone-sdk';
import { useState } from 'react';
function DeleteButton() {
const [visible, setVisible] = useState(false);
return (
<>
<Pressable onPress={() => setVisible(true)}>
<Text>Delete</Text>
</Pressable>
<Alert
visible={visible}
title="Delete item?"
message="This cannot be undone."
actions={[
{
label: 'Cancel',
style: 'cancel',
onPress: () => setVisible(false),
},
{
label: 'Delete',
style: 'destructive',
onPress: () => {
deleteItem();
setVisible(false);
},
},
]}
/>
</>
);
}
Dialog
A structured dialog with optional close button, custom children, and a footer slot.
| Prop | Type | Default | Description |
|---|---|---|---|
visible | boolean | — | Controls visibility |
onClose | () => void | — | Close handler |
title? | string | — | Dialog heading |
description? | string | — | Subtitle text below heading |
showCloseButton? | boolean | true | Show the X button in the top-right corner |
children | React.ReactNode | — | Dialog body content |
footer? | React.ReactNode | — | Footer slot (typically action buttons) |
size? | 'sm' | 'md' | 'lg' | 'md' | Dialog width |
import { Dialog, Stack, Text, Pressable, TextInput } from '@objectifthunes/limestone-sdk';
import { useState } from 'react';
function EditNameDialog({ visible, onClose }: { visible: boolean; onClose: () => void }) {
const [name, setName] = useState('');
return (
<Dialog
visible={visible}
onClose={onClose}
title="Edit display name"
description="This name will be visible to other users."
size="md"
footer={
<Stack direction="horizontal" gap="md" justify="flex-end">
<Pressable onPress={onClose} bg="muted" rounded="md" px="lg" py="sm" center>
<Text variant="label">Cancel</Text>
</Pressable>
<Pressable onPress={() => saveName(name)} bg="primary" rounded="md" px="lg" py="sm" center>
<Text color="primaryForeground" variant="label">Save</Text>
</Pressable>
</Stack>
}
>
<TextInput
value={name}
onChangeText={setName}
label="Display name"
variant="outline"
/>
</Dialog>
);
}
ProgressBar
A horizontal bar showing completion percentage.
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | — | Progress (0–100) |
color? | string | primary | Filled track color |
trackColor? | string | muted | Background track color |
height? | number | — | Bar height in pixels |
pill? | boolean | false | Fully rounded ends |
animated? | boolean | true | Animate value changes |
label? | string | — | Text label rendered above the bar |
showValue? | boolean | false | Show percentage value |
import { ProgressBar } from '@objectifthunes/limestone-sdk';
function UploadProgress({ percent }: { percent: number }) {
return (
<ProgressBar
value={percent}
label="Uploading…"
showValue
pill
animated
/>
);
}
ProgressCircle
A circular progress indicator with an optional center slot.
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | — | Progress (0–100) |
size? | number | 64 | Circle diameter in pixels |
strokeWidth? | number | 6 | Arc stroke width |
color? | string | primary | Arc color |
trackColor? | string | muted | Background ring color |
children? | React.ReactNode | — | Content rendered at center |
import { ProgressCircle, Text } from '@objectifthunes/limestone-sdk';
function StorageIndicator({ usedPercent }: { usedPercent: number }) {
return (
<ProgressCircle value={usedPercent} size={80} strokeWidth={8}>
<Text variant="label" weight="bold">{usedPercent}%</Text>
</ProgressCircle>
);
}
Spinner
An activity indicator that maps token sizes to the native small / large variants.
| Prop | Type | Default | Description |
|---|---|---|---|
size? | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Spinner size (xs/sm/md → small; lg/xl → large) |
color? | string | primary | Spinner tint color |
import { Spinner, Stack, Text } from '@objectifthunes/limestone-sdk';
function LoadingState() {
return (
<Stack center flex={1} gap="md">
<Spinner size="lg" />
<Text variant="caption" color="mutedForeground">Loading…</Text>
</Stack>
);
}
Badge
A small indicator overlaid on a child element. Supports count mode and dot mode.
| Prop | Type | Default | Description |
|---|---|---|---|
count? | number | — | Number to display; hidden when 0 |
maxCount? | number | 99 | Values above this show as {maxCount}+ |
dot? | boolean | false | Render a solid dot instead of a count |
color? | string | destructive | Badge background color |
textColor? | string | destructiveForeground | Badge text color |
size? | SpacingProp | 'sm' | Badge diameter |
placement? | 'top-right' | 'top-left' | 'top-right' | Position relative to the child |
children | React.ReactNode | — | The element the badge overlays |
import { Badge, Icon } from '@objectifthunes/limestone-sdk';
// Count mode — shows number
function NotificationIcon({ unreadCount }: { unreadCount: number }) {
return (
<Badge count={unreadCount} maxCount={99} placement="top-right">
<Icon name="bell" size="lg" />
</Badge>
);
}
// Dot mode — shows presence indicator
function OnlineAvatar() {
return (
<Badge dot color="green" placement="top-right">
<Box w={40} h={40} rounded="full" bg="muted" />
</Badge>
);
}
Banner
A full-width inline message with four severity variants.
| Prop | Type | Default | Description |
|---|---|---|---|
message | string | — | Primary message text |
title? | string | — | Bold heading above the message |
variant | 'info' | 'success' | 'warning' | 'error' | — | Color scheme and default icon |
icon? | React.ReactElement | — | Override the default variant icon |
dismissible? | boolean | false | Show a dismiss button |
onDismiss? | () => void | — | Called when the dismiss button is pressed |
action? | { label: string; onPress: () => void } | — | Optional inline action link |
import { Banner } from '@objectifthunes/limestone-sdk';
// Info
<Banner
variant="info"
title="New version available"
message="Update the app to get the latest features."
action={{ label: 'Update now', onPress: openAppStore }}
/>
// Success
<Banner
variant="success"
message="Your profile has been updated successfully."
dismissible
onDismiss={() => setShowBanner(false)}
/>
// Warning
<Banner
variant="warning"
title="Subscription expiring"
message="Your plan renews in 3 days."
/>
// Error
<Banner
variant="error"
title="Payment failed"
message="Please update your billing information."
action={{ label: 'Fix now', onPress: openBilling }}
/>
ConnectionStatus
A persistent bar that appears at the top of the screen when the device loses its internet connection, and auto-dismisses when connectivity is restored. It reads from the NetworkState in the Limestone store automatically.
| Prop | Type | Default | Description |
|---|---|---|---|
offlineMessage? | string | 'No internet connection' | Text shown while offline |
onlineMessage? | string | 'Back online' | Text shown for a brief moment when connection is restored |
showOnlineMessage? | boolean | true | Flash the “back online” message before hiding the bar |
onlineDuration? | number | 2000 | Milliseconds the “back online” bar stays visible |
variant? | 'banner' | 'toast' | 'banner' | Render as a full-width top banner or a small toast |
accessibilityLabel? | string | — | Accessibility label |
testID? | string | — | Test identifier |
Setup
Place ConnectionStatus once at your app root, alongside ToastContainer:
import { ConnectionStatus } from '@objectifthunes/limestone-sdk';
export default function App() {
return (
<LimestoneProvider config={config}>
<RootNavigator />
<ToastContainer position="top" />
<ConnectionStatus />
</LimestoneProvider>
);
}
Custom messages
<ConnectionStatus
offlineMessage="You're offline — changes will sync when reconnected."
showOnlineMessage
onlineMessage="Connected!"
onlineDuration={3000}
/>