@fleet-ui/components
v0.1.0
Published
Cross-platform UI components for Fleet UI
Readme
@fleet-ui/components
Cross-platform UI components for React and React Native, built with React Native Unistyles.
Installation
npm install @my-sdk/components
# or
pnpm add @my-sdk/componentsPeer Dependencies
Make sure you have these installed:
npm install react react-native react-native-unistylesUsage
import { Button, Input } from '@my-sdk/components';
function MyApp() {
return (
<View>
<Button onPress={() => console.log('pressed')}>
Click me
</Button>
<Input placeholder="Enter text" />
</View>
);
}Adding New Components
Follow this structure when adding a new component:
1. Create Component Directory
src/ComponentName/
├── ComponentName.tsx # Shared types and logic
├── ComponentName.native.tsx # React Native implementation
├── ComponentName.web.tsx # Web implementation
├── ComponentName.test.tsx # Unit tests
└── index.ts # Exports2. Example Component Structure
ComponentName.tsx (Shared)
import type { ViewStyle } from 'react-native';
import type { BaseComponentProps } from '@my-sdk/shared';
export interface ComponentNameProps extends BaseComponentProps {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
onPress?: () => void;
children: React.ReactNode;
}
// Shared logic, utilities, or constants
export const COMPONENT_CONSTANTS = {
// ...
};ComponentName.native.tsx (React Native)
import React from 'react';
import { Pressable, Text } from 'react-native';
import { createStyleSheet, useStyles } from 'react-native-unistyles';
import type { ComponentNameProps } from './ComponentName';
export const ComponentName: React.FC<ComponentNameProps> = ({
variant = 'primary',
size = 'md',
onPress,
children,
testID,
}) => {
const { styles } = useStyles(stylesheet, { variant, size });
return (
<Pressable style={styles.container} onPress={onPress} testID={testID}>
<Text style={styles.text}>{children}</Text>
</Pressable>
);
};
const stylesheet = createStyleSheet((theme) => ({
container: {
backgroundColor: theme.colors.primary,
padding: theme.spacing.md,
borderRadius: theme.borderRadius.md,
variants: {
variant: {
primary: { backgroundColor: theme.colors.primary },
secondary: { backgroundColor: theme.colors.secondary },
},
size: {
sm: { padding: theme.spacing.sm },
md: { padding: theme.spacing.md },
lg: { padding: theme.spacing.lg },
},
},
},
text: {
color: theme.colors.white,
},
}));ComponentName.web.tsx (Web)
import React from 'react';
import { createStyleSheet, useStyles } from 'react-native-unistyles';
import type { ComponentNameProps } from './ComponentName';
export const ComponentName: React.FC<ComponentNameProps> = ({
variant = 'primary',
size = 'md',
onPress,
children,
testID,
}) => {
const { styles } = useStyles(stylesheet, { variant, size });
return (
<button style={styles.container} onClick={onPress} data-testid={testID}>
{children}
</button>
);
};
const stylesheet = createStyleSheet((theme) => ({
container: {
backgroundColor: theme.colors.primary,
padding: theme.spacing.md,
borderRadius: theme.borderRadius.md,
border: 'none',
cursor: 'pointer',
variants: {
variant: {
primary: { backgroundColor: theme.colors.primary },
secondary: { backgroundColor: theme.colors.secondary },
},
size: {
sm: { padding: theme.spacing.sm },
md: { padding: theme.spacing.md },
lg: { padding: theme.spacing.lg },
},
},
},
}));ComponentName.test.tsx (Tests)
import React from 'react';
import { render, fireEvent } from '@testing-library/react-native';
import { ComponentName } from './ComponentName';
describe('ComponentName', () => {
it('renders correctly', () => {
const { getByText } = render(<ComponentName>Test</ComponentName>);
expect(getByText('Test')).toBeTruthy();
});
it('handles press events', () => {
const onPress = jest.fn();
const { getByText } = render(
<ComponentName onPress={onPress}>Press me</ComponentName>
);
fireEvent.press(getByText('Press me'));
expect(onPress).toHaveBeenCalledTimes(1);
});
});Playground examples
Document all variants and states in the Playground app under apps/playground/app/components/.
index.ts (Exports)
export { ComponentName } from './ComponentName';
export type { ComponentNameProps } from './ComponentName';3. Update Main Index
Add to src/index.ts:
export * from './ComponentName';Platform Resolution
React Native automatically resolves platform-specific files:
- On iOS/Android:
ComponentName.native.tsxis used - On Web:
ComponentName.web.tsxis used - Shared types/logic:
ComponentName.tsxis used by both
Best Practices
- Use Unistyles for styling - Ensures consistency and theme support
- Write tests - Maintain 80%+ coverage
- Add Playground examples - Document all variants and states
- Export types - Enable type-safe usage
- Use tokens - Import from
@my-sdk/tokensfor colors, spacing, etc. - Platform-specific code - Keep platform differences minimal and isolated
Available Components
Currently no components are available. Start adding components following the guide above!
License
MIT
