mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-16 21:59:39 +02:00
- Add uload project with apps/web structure
- Reorganize from flat to monorepo structure
- Remove PocketBase binary and local data
- Update to pnpm and @uload/web namespace
- Add picture project to monorepo
- Remove embedded git repository
- Unify all package names to @{project}/{app} schema:
- @maerchenzauber/* (was @storyteller/*)
- @manacore/* (was manacore-*, manacore)
- @manadeck/* (was web, backend, manadeck)
- @memoro/* (was memoro-web, landing, memoro)
- @picture/* (already unified)
- @uload/web
- Add convenient dev scripts for all apps:
- pnpm dev:{project}:web
- pnpm dev:{project}:landing
- pnpm dev:{project}:mobile
- pnpm dev:{project}:backend
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
173 lines
3.6 KiB
TypeScript
173 lines
3.6 KiB
TypeScript
import { forwardRef } from 'react';
|
|
import { Text as RNText, TextProps as RNTextProps, TextStyle } from 'react-native';
|
|
import { useTheme } from '~/contexts/ThemeContext';
|
|
|
|
type TextVariant =
|
|
| 'h1'
|
|
| 'h2'
|
|
| 'h3'
|
|
| 'h4'
|
|
| 'title'
|
|
| 'body'
|
|
| 'bodyLarge'
|
|
| 'bodySmall'
|
|
| 'caption'
|
|
| 'label'
|
|
| 'button';
|
|
|
|
type TextColor =
|
|
| 'primary'
|
|
| 'secondary'
|
|
| 'tertiary'
|
|
| 'inverse'
|
|
| 'error'
|
|
| 'success'
|
|
| 'warning';
|
|
|
|
type TextWeight = 'regular' | 'medium' | 'semibold' | 'bold';
|
|
|
|
type TextProps = {
|
|
variant?: TextVariant;
|
|
color?: TextColor;
|
|
weight?: TextWeight;
|
|
align?: 'left' | 'center' | 'right';
|
|
children?: React.ReactNode;
|
|
} & RNTextProps;
|
|
|
|
export const Text = forwardRef<RNText, TextProps>(({
|
|
variant = 'body',
|
|
color = 'primary',
|
|
weight,
|
|
align = 'left',
|
|
style,
|
|
children,
|
|
...props
|
|
}, ref) => {
|
|
const { theme } = useTheme();
|
|
|
|
// Variant styles
|
|
const getVariantStyle = (): TextStyle => {
|
|
switch (variant) {
|
|
case 'h1':
|
|
return {
|
|
fontSize: 32,
|
|
fontWeight: '700',
|
|
lineHeight: 40,
|
|
};
|
|
case 'h2':
|
|
return {
|
|
fontSize: 28,
|
|
fontWeight: '700',
|
|
lineHeight: 36,
|
|
};
|
|
case 'h3':
|
|
return {
|
|
fontSize: 24,
|
|
fontWeight: '600',
|
|
lineHeight: 32,
|
|
};
|
|
case 'h4':
|
|
return {
|
|
fontSize: 20,
|
|
fontWeight: '600',
|
|
lineHeight: 28,
|
|
};
|
|
case 'title':
|
|
return {
|
|
fontSize: 44,
|
|
fontWeight: '800',
|
|
lineHeight: 52,
|
|
};
|
|
case 'bodyLarge':
|
|
return {
|
|
fontSize: 18,
|
|
fontWeight: '400',
|
|
lineHeight: 28,
|
|
};
|
|
case 'body':
|
|
return {
|
|
fontSize: 16,
|
|
fontWeight: '400',
|
|
lineHeight: 24,
|
|
};
|
|
case 'bodySmall':
|
|
return {
|
|
fontSize: 14,
|
|
fontWeight: '400',
|
|
lineHeight: 20,
|
|
};
|
|
case 'caption':
|
|
return {
|
|
fontSize: 12,
|
|
fontWeight: '400',
|
|
lineHeight: 16,
|
|
};
|
|
case 'label':
|
|
return {
|
|
fontSize: 14,
|
|
fontWeight: '500',
|
|
lineHeight: 20,
|
|
};
|
|
case 'button':
|
|
return {
|
|
fontSize: 16,
|
|
fontWeight: '600',
|
|
lineHeight: 24,
|
|
};
|
|
default:
|
|
return {};
|
|
}
|
|
};
|
|
|
|
// Color mapping
|
|
const getTextColor = (): string => {
|
|
switch (color) {
|
|
case 'primary':
|
|
return theme.colors.text.primary;
|
|
case 'secondary':
|
|
return theme.colors.text.secondary;
|
|
case 'tertiary':
|
|
return theme.colors.text.tertiary;
|
|
case 'inverse':
|
|
return theme.colors.text.inverse;
|
|
case 'error':
|
|
return theme.colors.error;
|
|
case 'success':
|
|
return theme.colors.success;
|
|
case 'warning':
|
|
return theme.colors.warning;
|
|
default:
|
|
return theme.colors.text.primary;
|
|
}
|
|
};
|
|
|
|
// Weight mapping
|
|
const getFontWeight = (): TextStyle['fontWeight'] => {
|
|
if (weight) {
|
|
const weightMap: Record<TextWeight, TextStyle['fontWeight']> = {
|
|
regular: '400',
|
|
medium: '500',
|
|
semibold: '600',
|
|
bold: '700',
|
|
};
|
|
return weightMap[weight];
|
|
}
|
|
return undefined;
|
|
};
|
|
|
|
const textStyle: TextStyle = {
|
|
...getVariantStyle(),
|
|
color: getTextColor(),
|
|
textAlign: align,
|
|
...(weight && { fontWeight: getFontWeight() }),
|
|
...(style as TextStyle),
|
|
};
|
|
|
|
return (
|
|
<RNText ref={ref} style={textStyle} {...props}>
|
|
{children}
|
|
</RNText>
|
|
);
|
|
});
|
|
|
|
Text.displayName = 'Text';
|