Button
Buttons are the primary way users interact with Synchronicity applications. They trigger actions, submit forms, and navigate between screens.
Preview
Section titled “Preview”Variants
Section titled “Variants”Primary
Section titled “Primary”The primary button is used for the most important action on a screen. Use sparingly—typically one per view.
<Button variant="primary" onPress={handleCast}> Cast Hexagram</Button>Usage: Main CTAs, form submissions, primary actions
Secondary
Section titled “Secondary”Secondary buttons are for supporting actions that don’t need visual priority.
<Button variant="secondary" onPress={handleSave}> Save Reading</Button>Usage: Secondary actions, alternatives to primary
Ghost buttons are the most subtle. Use for tertiary actions or navigation.
<Button variant="ghost" onPress={handleLearnMore}> Learn More</Button>Usage: Tertiary actions, cancel buttons, navigation
Destructive
Section titled “Destructive”For dangerous or irreversible actions.
<Button variant="destructive" onPress={handleDelete}> Delete Reading</Button>Usage: Delete, remove, disconnect actions
| Size | Height | Font Size | Usage |
|---|---|---|---|
sm | 36px | 13px | Compact spaces, toolbars |
md | 44px | 15px | Default, most cases |
lg | 52px | 17px | Hero sections, primary CTAs |
<Button size="sm">Small</Button><Button size="md">Medium</Button><Button size="lg">Large</Button>States
Section titled “States”Default
Section titled “Default”Hover over the button above to see the hover state with subtle glow effect.
Pressed
Section titled “Pressed”Disabled
Section titled “Disabled”<Button disabled>Cannot Press</Button>Loading
Section titled “Loading”<Button loading>Processing</Button>With Icons
Section titled “With Icons”Icons can be placed before or after the button label.
<Button icon={<CastIcon />} iconPosition="left"> Cast Now</Button>
<Button icon={<ShareIcon />} iconPosition="right"> Share</Button>Icon Only
Section titled “Icon Only”For icon-only buttons, always include an accessibility label.
<Button icon={<MenuIcon />} accessibilityLabel="Open menu"/>Full Width
Section titled “Full Width”<Button fullWidth>Full Width Button</Button>API Reference
Section titled “API Reference”| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'ghost' | 'destructive' | 'primary' | Visual style |
size | 'sm' | 'md' | 'lg' | 'md' | Button size |
disabled | boolean | false | Disable interaction |
loading | boolean | false | Show loading state |
icon | ReactNode | - | Icon element |
iconPosition | 'left' | 'right' | 'left' | Icon placement |
fullWidth | boolean | false | Expand to container |
onPress | () => void | - | Press handler |
accessibilityLabel | string | - | Screen reader label |
haptic | 'light' | 'medium' | 'heavy' | 'light' | Haptic feedback |
Tokens Used
Section titled “Tokens Used”import { button } from '@synchronicity/tokens/components';
// Colorsbutton.primary.background // #d4af37button.primary.text // #0a0a0fbutton.secondary.border // #d4af37
// Sizingbutton.height.md // 44button.padding.horizontal.md // 16button.borderRadius // 8
// Typographybutton.fontSize.md // 15button.fontWeight // '600'Usage Guidelines
Section titled “Usage Guidelines”- Use primary buttons for the main action on each screen
- Provide clear, action-oriented labels (“Cast Hexagram”, not “Submit”)
- Include haptic feedback for tactile response
- Maintain minimum touch target (44x44 points)
- Use multiple primary buttons in the same view
- Use vague labels like “Click Here” or “OK”
- Disable buttons without explanation
- Use destructive styling for non-destructive actions
Accessibility
Section titled “Accessibility”- Touch target: Minimum 44x44 points
- Color contrast: 9.4:1 for gold on dark (AAA compliant)
- Focus indicator: 2px gold outline with offset
- Screen reader: Announces button role and label
- Disabled state: Reduced opacity (0.5), not just color change
<Button onPress={handleAction} accessibilityLabel="Cast a new hexagram using three coins" accessibilityHint="Double tap to begin casting"> Cast Hexagram</Button>Complete Example
Section titled “Complete Example”import { Button } from '@synchronicity/react-native';import { useState } from 'react';
function CastingScreen() { const [isLoading, setIsLoading] = useState(false);
const handleCast = async () => { setIsLoading(true); try { await castHexagram(); } finally { setIsLoading(false); } };
return ( <View style={styles.container}> <Button variant="primary" size="lg" loading={isLoading} onPress={handleCast} haptic="medium" fullWidth > {isLoading ? 'Casting...' : 'Cast Hexagram'} </Button>
<Button variant="ghost" onPress={goBack} style={{ marginTop: 16 }} > Cancel </Button> </View> );}