@mrmeg/expo-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -0
- package/dist/components/Accordion.d.ts +54 -0
- package/dist/components/Accordion.js +149 -0
- package/dist/components/Alert.d.ts +30 -0
- package/dist/components/Alert.js +25 -0
- package/dist/components/AnimatedView.d.ts +55 -0
- package/dist/components/AnimatedView.js +39 -0
- package/dist/components/Badge.d.ts +23 -0
- package/dist/components/Badge.js +74 -0
- package/dist/components/BottomSheet.d.ts +74 -0
- package/dist/components/BottomSheet.js +513 -0
- package/dist/components/Button.d.ts +129 -0
- package/dist/components/Button.js +216 -0
- package/dist/components/Card.d.ts +42 -0
- package/dist/components/Card.js +126 -0
- package/dist/components/Checkbox.d.ts +39 -0
- package/dist/components/Checkbox.js +96 -0
- package/dist/components/Collapsible.d.ts +67 -0
- package/dist/components/Collapsible.js +38 -0
- package/dist/components/Dialog.d.ts +140 -0
- package/dist/components/Dialog.js +167 -0
- package/dist/components/DismissKeyboard.d.ts +15 -0
- package/dist/components/DismissKeyboard.js +13 -0
- package/dist/components/Drawer.d.ts +74 -0
- package/dist/components/Drawer.js +423 -0
- package/dist/components/DropdownMenu.d.ts +120 -0
- package/dist/components/DropdownMenu.js +211 -0
- package/dist/components/EmptyState.d.ts +42 -0
- package/dist/components/EmptyState.js +58 -0
- package/dist/components/ErrorBoundary.d.ts +53 -0
- package/dist/components/ErrorBoundary.js +75 -0
- package/dist/components/Icon.d.ts +46 -0
- package/dist/components/Icon.js +40 -0
- package/dist/components/InputOTP.d.ts +72 -0
- package/dist/components/InputOTP.js +155 -0
- package/dist/components/Label.d.ts +61 -0
- package/dist/components/Label.js +72 -0
- package/dist/components/MaxWidthContainer.d.ts +58 -0
- package/dist/components/MaxWidthContainer.js +64 -0
- package/dist/components/Notification.d.ts +26 -0
- package/dist/components/Notification.js +230 -0
- package/dist/components/Popover.d.ts +79 -0
- package/dist/components/Popover.js +91 -0
- package/dist/components/Progress.d.ts +28 -0
- package/dist/components/Progress.js +107 -0
- package/dist/components/RadioGroup.d.ts +65 -0
- package/dist/components/RadioGroup.js +142 -0
- package/dist/components/Select.d.ts +88 -0
- package/dist/components/Select.js +172 -0
- package/dist/components/Separator.d.ts +83 -0
- package/dist/components/Separator.js +85 -0
- package/dist/components/Skeleton.d.ts +68 -0
- package/dist/components/Skeleton.js +99 -0
- package/dist/components/Slider.d.ts +24 -0
- package/dist/components/Slider.js +162 -0
- package/dist/components/StatusBar.d.ts +1 -0
- package/dist/components/StatusBar.js +19 -0
- package/dist/components/StyledText.d.ts +161 -0
- package/dist/components/StyledText.js +193 -0
- package/dist/components/Switch.d.ts +44 -0
- package/dist/components/Switch.js +129 -0
- package/dist/components/Tabs.d.ts +31 -0
- package/dist/components/Tabs.js +127 -0
- package/dist/components/TextInput.d.ts +120 -0
- package/dist/components/TextInput.js +263 -0
- package/dist/components/Toggle.d.ts +106 -0
- package/dist/components/Toggle.js +150 -0
- package/dist/components/ToggleGroup.d.ts +80 -0
- package/dist/components/ToggleGroup.js +189 -0
- package/dist/components/Tooltip.d.ts +121 -0
- package/dist/components/Tooltip.js +132 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +35 -0
- package/dist/constants/colors.d.ts +82 -0
- package/dist/constants/colors.js +116 -0
- package/dist/constants/fonts.d.ts +32 -0
- package/dist/constants/fonts.js +91 -0
- package/dist/constants/index.d.ts +3 -0
- package/dist/constants/index.js +3 -0
- package/dist/constants/spacing.d.ts +40 -0
- package/dist/constants/spacing.js +48 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/useDimensions.d.ts +19 -0
- package/dist/hooks/useDimensions.js +55 -0
- package/dist/hooks/useReduceMotion.d.ts +5 -0
- package/dist/hooks/useReduceMotion.js +64 -0
- package/dist/hooks/useResources.d.ts +12 -0
- package/dist/hooks/useResources.js +56 -0
- package/dist/hooks/useScalePress.d.ts +57 -0
- package/dist/hooks/useScalePress.js +55 -0
- package/dist/hooks/useStaggeredEntrance.d.ts +67 -0
- package/dist/hooks/useStaggeredEntrance.js +74 -0
- package/dist/hooks/useTheme.d.ts +88 -0
- package/dist/hooks/useTheme.js +328 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/lib/animations.d.ts +1 -0
- package/dist/lib/animations.js +3 -0
- package/dist/lib/haptics.d.ts +3 -0
- package/dist/lib/haptics.js +29 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.js +3 -0
- package/dist/lib/sentry.d.ts +16 -0
- package/dist/lib/sentry.js +55 -0
- package/dist/state/globalUIStore.d.ts +30 -0
- package/dist/state/globalUIStore.js +8 -0
- package/dist/state/index.d.ts +2 -0
- package/dist/state/index.js +2 -0
- package/dist/state/themeStore.d.ts +6 -0
- package/dist/state/themeStore.js +38 -0
- package/package.json +92 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Platform, StyleSheet, View } from "react-native";
|
|
4
|
+
import { AnimatedView } from "./AnimatedView";
|
|
5
|
+
import { TextClassContext, TextColorContext } from "./StyledText";
|
|
6
|
+
import { useTheme } from "../hooks/useTheme";
|
|
7
|
+
import { spacing } from "../constants/spacing";
|
|
8
|
+
import * as TooltipPrimitive from "@rn-primitives/tooltip";
|
|
9
|
+
import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens";
|
|
10
|
+
import { palette } from "../constants/colors";
|
|
11
|
+
/**
|
|
12
|
+
* Tooltip Trigger Component
|
|
13
|
+
* The element that triggers the tooltip to appear on hover (web) or press (native)
|
|
14
|
+
*/
|
|
15
|
+
const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
16
|
+
/**
|
|
17
|
+
* FullWindowOverlay wrapper - uses native overlay on iOS for proper z-index handling
|
|
18
|
+
* On Android/Web, uses Fragment to avoid unnecessary nesting
|
|
19
|
+
*/
|
|
20
|
+
const FullWindowOverlay = Platform.OS === "ios" ? RNFullWindowOverlay : React.Fragment;
|
|
21
|
+
/**
|
|
22
|
+
* Tooltip Content Component
|
|
23
|
+
* The content that appears in the tooltip overlay
|
|
24
|
+
* Supports smart positioning, animations, and theme integration
|
|
25
|
+
*
|
|
26
|
+
* Features:
|
|
27
|
+
* - Side positioning (top, bottom, left, right - left/right web only)
|
|
28
|
+
* - Alignment options (start, center, end)
|
|
29
|
+
* - Visual variants (default, dark, light)
|
|
30
|
+
* - Smooth animations
|
|
31
|
+
* - Portal-based rendering for proper z-index
|
|
32
|
+
*/
|
|
33
|
+
function TooltipContent({ side = "top", align = "center", sideOffset = 4, portalHost, variant = "default", ...props }) {
|
|
34
|
+
const { theme, getShadowStyle, getContrastingColor } = useTheme();
|
|
35
|
+
// Determine colors based on variant
|
|
36
|
+
const getVariantColors = () => {
|
|
37
|
+
switch (variant) {
|
|
38
|
+
case "dark":
|
|
39
|
+
return {
|
|
40
|
+
background: palette.gray800,
|
|
41
|
+
border: palette.gray800,
|
|
42
|
+
text: palette.white,
|
|
43
|
+
};
|
|
44
|
+
case "light":
|
|
45
|
+
return {
|
|
46
|
+
background: palette.white,
|
|
47
|
+
border: palette.gray200,
|
|
48
|
+
text: palette.gray800,
|
|
49
|
+
};
|
|
50
|
+
case "default":
|
|
51
|
+
default:
|
|
52
|
+
return {
|
|
53
|
+
background: theme.colors.card,
|
|
54
|
+
border: theme.colors.border,
|
|
55
|
+
text: getContrastingColor(theme.colors.card, palette.white, palette.black),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const colors = getVariantColors();
|
|
60
|
+
const contentStyle = StyleSheet.flatten([
|
|
61
|
+
{
|
|
62
|
+
backgroundColor: colors.background,
|
|
63
|
+
borderColor: colors.border,
|
|
64
|
+
borderWidth: 1,
|
|
65
|
+
borderRadius: spacing.radiusMd,
|
|
66
|
+
paddingHorizontal: spacing.sm,
|
|
67
|
+
paddingVertical: spacing.xs,
|
|
68
|
+
maxWidth: 250,
|
|
69
|
+
...getShadowStyle("soft"),
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
72
|
+
return (_jsx(TooltipPrimitive.Portal, { hostName: portalHost, children: _jsx(FullWindowOverlay, { children: _jsx(TooltipPrimitive.Overlay, { style: Platform.select({ native: StyleSheet.absoluteFill }), children: _jsx(AnimatedView, { type: "fade", enterDuration: 150, children: _jsx(TextColorContext.Provider, { value: colors.text, children: _jsx(TextClassContext.Provider, { value: "", children: _jsx(TooltipPrimitive.Content, { side: side, align: align, sideOffset: sideOffset, style: contentStyle, ...props }) }) }) }) }) }) }));
|
|
73
|
+
}
|
|
74
|
+
function TooltipBody({ children, style, ...props }) {
|
|
75
|
+
return (_jsx(View, { style: [
|
|
76
|
+
{
|
|
77
|
+
paddingHorizontal: spacing.xxs,
|
|
78
|
+
paddingVertical: spacing.xxs,
|
|
79
|
+
},
|
|
80
|
+
style,
|
|
81
|
+
], ...props, children: children }));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Tooltip Root Component
|
|
85
|
+
* Manages tooltip state and provides context for trigger and content
|
|
86
|
+
*
|
|
87
|
+
* Usage:
|
|
88
|
+
* ```tsx
|
|
89
|
+
* // Basic tooltip
|
|
90
|
+
* <Tooltip>
|
|
91
|
+
* <TooltipTrigger asChild>
|
|
92
|
+
* <Button><Text>Hover me</Text></Button>
|
|
93
|
+
* </TooltipTrigger>
|
|
94
|
+
* <TooltipContent>
|
|
95
|
+
* <StyledText>Tooltip text</StyledText>
|
|
96
|
+
* </TooltipContent>
|
|
97
|
+
* </Tooltip>
|
|
98
|
+
*
|
|
99
|
+
* // With positioning
|
|
100
|
+
* <Tooltip>
|
|
101
|
+
* <TooltipTrigger asChild>
|
|
102
|
+
* <Icon as={Info} size={20} />
|
|
103
|
+
* </TooltipTrigger>
|
|
104
|
+
* <TooltipContent side="bottom" align="start">
|
|
105
|
+
* <StyledText>Information tooltip</StyledText>
|
|
106
|
+
* </TooltipContent>
|
|
107
|
+
* </Tooltip>
|
|
108
|
+
*
|
|
109
|
+
* // Dark variant
|
|
110
|
+
* <Tooltip>
|
|
111
|
+
* <TooltipTrigger asChild>
|
|
112
|
+
* <Button><Text>Help</Text></Button>
|
|
113
|
+
* </TooltipTrigger>
|
|
114
|
+
* <TooltipContent variant="dark">
|
|
115
|
+
* <StyledText>Dark tooltip</StyledText>
|
|
116
|
+
* </TooltipContent>
|
|
117
|
+
* </Tooltip>
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
function Tooltip({ delayDuration = 700, skipDelayDuration = 300, ...props }) {
|
|
121
|
+
return (_jsx(TooltipPrimitive.Root, { delayDuration: delayDuration, skipDelayDuration: skipDelayDuration, ...props }));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Tooltip Component with Sub-components
|
|
125
|
+
* Properly typed interface for dot notation access (e.g., Tooltip.Trigger)
|
|
126
|
+
*/
|
|
127
|
+
const TooltipComponent = Object.assign(Tooltip, {
|
|
128
|
+
Trigger: TooltipTrigger,
|
|
129
|
+
Content: TooltipContent,
|
|
130
|
+
Body: TooltipBody,
|
|
131
|
+
});
|
|
132
|
+
export { TooltipComponent as Tooltip, TooltipTrigger, TooltipContent, TooltipBody, };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export * from "./Accordion";
|
|
2
|
+
export * from "./Alert";
|
|
3
|
+
export * from "./AnimatedView";
|
|
4
|
+
export * from "./Badge";
|
|
5
|
+
export * from "./BottomSheet";
|
|
6
|
+
export * from "./Button";
|
|
7
|
+
export * from "./Card";
|
|
8
|
+
export * from "./Checkbox";
|
|
9
|
+
export * from "./Collapsible";
|
|
10
|
+
export * from "./Dialog";
|
|
11
|
+
export * from "./DismissKeyboard";
|
|
12
|
+
export * from "./Drawer";
|
|
13
|
+
export * from "./DropdownMenu";
|
|
14
|
+
export * from "./EmptyState";
|
|
15
|
+
export * from "./ErrorBoundary";
|
|
16
|
+
export * from "./Icon";
|
|
17
|
+
export * from "./InputOTP";
|
|
18
|
+
export * from "./Label";
|
|
19
|
+
export * from "./MaxWidthContainer";
|
|
20
|
+
export * from "./Notification";
|
|
21
|
+
export * from "./Popover";
|
|
22
|
+
export * from "./Progress";
|
|
23
|
+
export * from "./RadioGroup";
|
|
24
|
+
export * from "./Select";
|
|
25
|
+
export * from "./Separator";
|
|
26
|
+
export * from "./Skeleton";
|
|
27
|
+
export * from "./Slider";
|
|
28
|
+
export * from "./StatusBar";
|
|
29
|
+
export * from "./StyledText";
|
|
30
|
+
export * from "./Switch";
|
|
31
|
+
export * from "./Tabs";
|
|
32
|
+
export * from "./TextInput";
|
|
33
|
+
export * from "./Toggle";
|
|
34
|
+
export * from "./ToggleGroup";
|
|
35
|
+
export * from "./Tooltip";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export * from "./Accordion";
|
|
2
|
+
export * from "./Alert";
|
|
3
|
+
export * from "./AnimatedView";
|
|
4
|
+
export * from "./Badge";
|
|
5
|
+
export * from "./BottomSheet";
|
|
6
|
+
export * from "./Button";
|
|
7
|
+
export * from "./Card";
|
|
8
|
+
export * from "./Checkbox";
|
|
9
|
+
export * from "./Collapsible";
|
|
10
|
+
export * from "./Dialog";
|
|
11
|
+
export * from "./DismissKeyboard";
|
|
12
|
+
export * from "./Drawer";
|
|
13
|
+
export * from "./DropdownMenu";
|
|
14
|
+
export * from "./EmptyState";
|
|
15
|
+
export * from "./ErrorBoundary";
|
|
16
|
+
export * from "./Icon";
|
|
17
|
+
export * from "./InputOTP";
|
|
18
|
+
export * from "./Label";
|
|
19
|
+
export * from "./MaxWidthContainer";
|
|
20
|
+
export * from "./Notification";
|
|
21
|
+
export * from "./Popover";
|
|
22
|
+
export * from "./Progress";
|
|
23
|
+
export * from "./RadioGroup";
|
|
24
|
+
export * from "./Select";
|
|
25
|
+
export * from "./Separator";
|
|
26
|
+
export * from "./Skeleton";
|
|
27
|
+
export * from "./Slider";
|
|
28
|
+
export * from "./StatusBar";
|
|
29
|
+
export * from "./StyledText";
|
|
30
|
+
export * from "./Switch";
|
|
31
|
+
export * from "./Tabs";
|
|
32
|
+
export * from "./TextInput";
|
|
33
|
+
export * from "./Toggle";
|
|
34
|
+
export * from "./ToggleGroup";
|
|
35
|
+
export * from "./Tooltip";
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { navigationFonts } from "./fonts";
|
|
2
|
+
/**
|
|
3
|
+
* Raw color palette - use semantic colors in components instead
|
|
4
|
+
*
|
|
5
|
+
* Zinc-inspired neutral scale for a minimal, professional feel.
|
|
6
|
+
* Status colors aligned with Tailwind's default palette.
|
|
7
|
+
*/
|
|
8
|
+
declare const palette: {
|
|
9
|
+
readonly teal400: "#2dd4bf";
|
|
10
|
+
readonly teal500: "#14b8a6";
|
|
11
|
+
readonly teal600: "#0d9488";
|
|
12
|
+
readonly white: "#FFFFFF";
|
|
13
|
+
readonly gray50: "#FAFAFA";
|
|
14
|
+
readonly gray100: "#F4F4F5";
|
|
15
|
+
readonly gray200: "#E4E4E7";
|
|
16
|
+
readonly gray300: "#D4D4D8";
|
|
17
|
+
readonly gray400: "#A1A1AA";
|
|
18
|
+
readonly gray500: "#71717A";
|
|
19
|
+
readonly gray600: "#52525B";
|
|
20
|
+
readonly gray700: "#3F3F46";
|
|
21
|
+
readonly gray800: "#27272A";
|
|
22
|
+
readonly gray900: "#18181B";
|
|
23
|
+
readonly gray950: "#09090B";
|
|
24
|
+
readonly black: "#000000";
|
|
25
|
+
readonly dark900: "#09090B";
|
|
26
|
+
readonly dark800: "#18181B";
|
|
27
|
+
readonly dark700: "#27272A";
|
|
28
|
+
readonly dark600: "#3F3F46";
|
|
29
|
+
readonly dark400: "#A1A1AA";
|
|
30
|
+
readonly dark300: "#D4D4D8";
|
|
31
|
+
readonly dark100: "#F4F4F5";
|
|
32
|
+
readonly green500: "#22C55E";
|
|
33
|
+
readonly green400: "#4ADE80";
|
|
34
|
+
readonly amber500: "#F59E0B";
|
|
35
|
+
readonly amber400: "#FBBF24";
|
|
36
|
+
readonly red500: "#EF4444";
|
|
37
|
+
readonly red400: "#F87171";
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Semantic color interface - what colors mean in the UI
|
|
41
|
+
*/
|
|
42
|
+
export interface ThemeColors {
|
|
43
|
+
background: string;
|
|
44
|
+
foreground: string;
|
|
45
|
+
card: string;
|
|
46
|
+
cardForeground: string;
|
|
47
|
+
text: string;
|
|
48
|
+
textDim: string;
|
|
49
|
+
primary: string;
|
|
50
|
+
primaryForeground: string;
|
|
51
|
+
secondary: string;
|
|
52
|
+
secondaryForeground: string;
|
|
53
|
+
muted: string;
|
|
54
|
+
mutedForeground: string;
|
|
55
|
+
accent: string;
|
|
56
|
+
accentForeground: string;
|
|
57
|
+
destructive: string;
|
|
58
|
+
destructiveForeground: string;
|
|
59
|
+
success: string;
|
|
60
|
+
warning: string;
|
|
61
|
+
border: string;
|
|
62
|
+
overlay: string;
|
|
63
|
+
}
|
|
64
|
+
export interface Theme {
|
|
65
|
+
colors: ThemeColors;
|
|
66
|
+
dark: boolean;
|
|
67
|
+
fonts: typeof navigationFonts;
|
|
68
|
+
navigation: {
|
|
69
|
+
primary: string;
|
|
70
|
+
background: string;
|
|
71
|
+
card: string;
|
|
72
|
+
text: string;
|
|
73
|
+
border: string;
|
|
74
|
+
notification: string;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export interface Colors {
|
|
78
|
+
light: Theme;
|
|
79
|
+
dark: Theme;
|
|
80
|
+
}
|
|
81
|
+
export declare const colors: Colors;
|
|
82
|
+
export { palette };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { navigationFonts } from "./fonts";
|
|
2
|
+
/**
|
|
3
|
+
* Raw color palette - use semantic colors in components instead
|
|
4
|
+
*
|
|
5
|
+
* Zinc-inspired neutral scale for a minimal, professional feel.
|
|
6
|
+
* Status colors aligned with Tailwind's default palette.
|
|
7
|
+
*/
|
|
8
|
+
const palette = {
|
|
9
|
+
// Brand (accent)
|
|
10
|
+
teal400: "#2dd4bf",
|
|
11
|
+
teal500: "#14b8a6",
|
|
12
|
+
teal600: "#0d9488",
|
|
13
|
+
// Neutrals — zinc scale
|
|
14
|
+
white: "#FFFFFF",
|
|
15
|
+
gray50: "#FAFAFA",
|
|
16
|
+
gray100: "#F4F4F5",
|
|
17
|
+
gray200: "#E4E4E7",
|
|
18
|
+
gray300: "#D4D4D8",
|
|
19
|
+
gray400: "#A1A1AA",
|
|
20
|
+
gray500: "#71717A",
|
|
21
|
+
gray600: "#52525B",
|
|
22
|
+
gray700: "#3F3F46",
|
|
23
|
+
gray800: "#27272A",
|
|
24
|
+
gray900: "#18181B",
|
|
25
|
+
gray950: "#09090B",
|
|
26
|
+
black: "#000000",
|
|
27
|
+
// Dark mode surfaces — zinc-based
|
|
28
|
+
dark900: "#09090B",
|
|
29
|
+
dark800: "#18181B",
|
|
30
|
+
dark700: "#27272A",
|
|
31
|
+
dark600: "#3F3F46",
|
|
32
|
+
dark400: "#A1A1AA",
|
|
33
|
+
dark300: "#D4D4D8",
|
|
34
|
+
dark100: "#F4F4F5",
|
|
35
|
+
// Status
|
|
36
|
+
green500: "#22C55E",
|
|
37
|
+
green400: "#4ADE80",
|
|
38
|
+
amber500: "#F59E0B",
|
|
39
|
+
amber400: "#FBBF24",
|
|
40
|
+
red500: "#EF4444",
|
|
41
|
+
red400: "#F87171",
|
|
42
|
+
};
|
|
43
|
+
const lightTheme = {
|
|
44
|
+
dark: false,
|
|
45
|
+
fonts: navigationFonts,
|
|
46
|
+
colors: {
|
|
47
|
+
background: palette.white,
|
|
48
|
+
foreground: palette.gray950,
|
|
49
|
+
card: palette.gray50,
|
|
50
|
+
cardForeground: palette.gray950,
|
|
51
|
+
text: palette.gray950,
|
|
52
|
+
textDim: palette.gray500,
|
|
53
|
+
primary: palette.gray900,
|
|
54
|
+
primaryForeground: palette.gray50,
|
|
55
|
+
secondary: palette.teal500,
|
|
56
|
+
secondaryForeground: palette.white,
|
|
57
|
+
muted: palette.gray100,
|
|
58
|
+
mutedForeground: palette.gray500,
|
|
59
|
+
accent: palette.teal500,
|
|
60
|
+
accentForeground: palette.white,
|
|
61
|
+
destructive: palette.red500,
|
|
62
|
+
destructiveForeground: palette.white,
|
|
63
|
+
success: palette.green500,
|
|
64
|
+
warning: palette.amber500,
|
|
65
|
+
border: palette.gray200,
|
|
66
|
+
overlay: "rgba(0, 0, 0, 0.5)",
|
|
67
|
+
},
|
|
68
|
+
navigation: {
|
|
69
|
+
primary: palette.gray900,
|
|
70
|
+
background: palette.white,
|
|
71
|
+
card: palette.gray50,
|
|
72
|
+
text: palette.gray950,
|
|
73
|
+
border: palette.gray200,
|
|
74
|
+
notification: palette.teal500,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
const darkTheme = {
|
|
78
|
+
dark: true,
|
|
79
|
+
fonts: navigationFonts,
|
|
80
|
+
colors: {
|
|
81
|
+
background: palette.dark900,
|
|
82
|
+
foreground: palette.dark100,
|
|
83
|
+
card: palette.dark800,
|
|
84
|
+
cardForeground: palette.dark100,
|
|
85
|
+
text: palette.dark100,
|
|
86
|
+
textDim: palette.dark400,
|
|
87
|
+
primary: palette.gray50,
|
|
88
|
+
primaryForeground: palette.gray900,
|
|
89
|
+
secondary: palette.teal400,
|
|
90
|
+
secondaryForeground: palette.black,
|
|
91
|
+
muted: palette.dark700,
|
|
92
|
+
mutedForeground: palette.dark400,
|
|
93
|
+
accent: palette.teal400,
|
|
94
|
+
accentForeground: palette.gray900,
|
|
95
|
+
destructive: palette.red400,
|
|
96
|
+
destructiveForeground: palette.white,
|
|
97
|
+
success: palette.green400,
|
|
98
|
+
warning: palette.amber400,
|
|
99
|
+
border: palette.dark700,
|
|
100
|
+
overlay: "rgba(0, 0, 0, 0.7)",
|
|
101
|
+
},
|
|
102
|
+
navigation: {
|
|
103
|
+
primary: palette.gray50,
|
|
104
|
+
background: palette.dark900,
|
|
105
|
+
card: palette.dark800,
|
|
106
|
+
text: palette.dark100,
|
|
107
|
+
border: palette.dark700,
|
|
108
|
+
notification: palette.teal400,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
export const colors = {
|
|
112
|
+
light: lightTheme,
|
|
113
|
+
dark: darkTheme,
|
|
114
|
+
};
|
|
115
|
+
// Export palette for rare one-off cases
|
|
116
|
+
export { palette };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
type NavigationFontWeight = "normal" | "bold" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900";
|
|
2
|
+
interface FontStyle {
|
|
3
|
+
fontFamily: string;
|
|
4
|
+
fontWeight: NavigationFontWeight;
|
|
5
|
+
}
|
|
6
|
+
interface NavigationFonts {
|
|
7
|
+
regular: FontStyle;
|
|
8
|
+
medium: FontStyle;
|
|
9
|
+
bold: FontStyle;
|
|
10
|
+
heavy: FontStyle;
|
|
11
|
+
}
|
|
12
|
+
export declare const fontFamilies: {
|
|
13
|
+
serif: {
|
|
14
|
+
regular: string;
|
|
15
|
+
bold: string;
|
|
16
|
+
};
|
|
17
|
+
sansSerif: {
|
|
18
|
+
regular: string;
|
|
19
|
+
bold: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Typography scale — Tailwind-matching sizes for consistent text hierarchy.
|
|
24
|
+
* Components can progressively adopt these tokens.
|
|
25
|
+
*/
|
|
26
|
+
export type TypographySize = "xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl" | "4xl";
|
|
27
|
+
export declare const typography: Record<TypographySize, {
|
|
28
|
+
fontSize: number;
|
|
29
|
+
lineHeight: number;
|
|
30
|
+
}>;
|
|
31
|
+
export declare const navigationFonts: NavigationFonts;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
2
|
+
// Web font stack fallback
|
|
3
|
+
const WEB_FONT_STACK = "system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"";
|
|
4
|
+
export const fontFamilies = {
|
|
5
|
+
serif: Platform.select({
|
|
6
|
+
ios: { regular: "Georgia", bold: "Georgia" },
|
|
7
|
+
web: { regular: "Georgia, 'Times New Roman', serif", bold: "Georgia, 'Times New Roman', serif" },
|
|
8
|
+
default: { regular: "serif", bold: "serif" },
|
|
9
|
+
}),
|
|
10
|
+
sansSerif: Platform.select({
|
|
11
|
+
web: {
|
|
12
|
+
regular: `"Lato", ${WEB_FONT_STACK}`,
|
|
13
|
+
bold: `"Lato", ${WEB_FONT_STACK}`,
|
|
14
|
+
},
|
|
15
|
+
ios: {
|
|
16
|
+
regular: "System",
|
|
17
|
+
bold: "System",
|
|
18
|
+
},
|
|
19
|
+
default: {
|
|
20
|
+
regular: "sans-serif",
|
|
21
|
+
bold: "sans-serif",
|
|
22
|
+
},
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
export const typography = {
|
|
26
|
+
xs: { fontSize: 12, lineHeight: 16 },
|
|
27
|
+
sm: { fontSize: 14, lineHeight: 20 },
|
|
28
|
+
base: { fontSize: 16, lineHeight: 24 },
|
|
29
|
+
lg: { fontSize: 18, lineHeight: 28 },
|
|
30
|
+
xl: { fontSize: 20, lineHeight: 28 },
|
|
31
|
+
"2xl": { fontSize: 24, lineHeight: 32 },
|
|
32
|
+
"3xl": { fontSize: 30, lineHeight: 36 },
|
|
33
|
+
"4xl": { fontSize: 36, lineHeight: 40 },
|
|
34
|
+
};
|
|
35
|
+
// Navigation theme fonts configuration
|
|
36
|
+
export const navigationFonts = Platform.select({
|
|
37
|
+
web: {
|
|
38
|
+
regular: {
|
|
39
|
+
fontFamily: fontFamilies.sansSerif.regular || WEB_FONT_STACK,
|
|
40
|
+
fontWeight: "400",
|
|
41
|
+
},
|
|
42
|
+
medium: {
|
|
43
|
+
fontFamily: fontFamilies.sansSerif.regular || WEB_FONT_STACK,
|
|
44
|
+
fontWeight: "500",
|
|
45
|
+
},
|
|
46
|
+
bold: {
|
|
47
|
+
fontFamily: fontFamilies.sansSerif.bold || WEB_FONT_STACK,
|
|
48
|
+
fontWeight: "600",
|
|
49
|
+
},
|
|
50
|
+
heavy: {
|
|
51
|
+
fontFamily: fontFamilies.sansSerif.bold || WEB_FONT_STACK,
|
|
52
|
+
fontWeight: "700",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
ios: {
|
|
56
|
+
regular: {
|
|
57
|
+
fontFamily: fontFamilies.sansSerif.regular || "System",
|
|
58
|
+
fontWeight: "400",
|
|
59
|
+
},
|
|
60
|
+
medium: {
|
|
61
|
+
fontFamily: fontFamilies.sansSerif.regular || "System",
|
|
62
|
+
fontWeight: "500",
|
|
63
|
+
},
|
|
64
|
+
bold: {
|
|
65
|
+
fontFamily: fontFamilies.sansSerif.bold || "System",
|
|
66
|
+
fontWeight: "600",
|
|
67
|
+
},
|
|
68
|
+
heavy: {
|
|
69
|
+
fontFamily: fontFamilies.sansSerif.bold || "System",
|
|
70
|
+
fontWeight: "700",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
default: {
|
|
74
|
+
regular: {
|
|
75
|
+
fontFamily: fontFamilies.sansSerif.regular || "sans-serif",
|
|
76
|
+
fontWeight: "normal",
|
|
77
|
+
},
|
|
78
|
+
medium: {
|
|
79
|
+
fontFamily: fontFamilies.sansSerif.regular || "sans-serif-medium",
|
|
80
|
+
fontWeight: "normal",
|
|
81
|
+
},
|
|
82
|
+
bold: {
|
|
83
|
+
fontFamily: fontFamilies.sansSerif.bold || "sans-serif",
|
|
84
|
+
fontWeight: "600",
|
|
85
|
+
},
|
|
86
|
+
heavy: {
|
|
87
|
+
fontFamily: fontFamilies.sansSerif.bold || "sans-serif",
|
|
88
|
+
fontWeight: "700",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spacing Constants
|
|
3
|
+
*
|
|
4
|
+
* A consistent spacing scale based on an 8px base unit.
|
|
5
|
+
* Use these constants throughout the app for consistent spacing.
|
|
6
|
+
*/
|
|
7
|
+
export declare const spacing: {
|
|
8
|
+
readonly base: 8;
|
|
9
|
+
readonly xxs: 2;
|
|
10
|
+
readonly xs: 4;
|
|
11
|
+
readonly sm: 8;
|
|
12
|
+
readonly md: 16;
|
|
13
|
+
readonly lg: 24;
|
|
14
|
+
readonly xl: 32;
|
|
15
|
+
readonly xxl: 48;
|
|
16
|
+
readonly xxxl: 64;
|
|
17
|
+
readonly gutter: 16;
|
|
18
|
+
readonly gutterVertical: 24;
|
|
19
|
+
readonly screenPadding: 16;
|
|
20
|
+
readonly buttonPadding: 10;
|
|
21
|
+
readonly inputPadding: 10;
|
|
22
|
+
readonly cardPadding: 16;
|
|
23
|
+
readonly sectionSpacing: 32;
|
|
24
|
+
readonly listItemSpacing: 8;
|
|
25
|
+
readonly radiusNone: 0;
|
|
26
|
+
readonly radiusXs: 2;
|
|
27
|
+
readonly radiusSm: 4;
|
|
28
|
+
readonly radiusMd: 6;
|
|
29
|
+
readonly radiusLg: 8;
|
|
30
|
+
readonly radiusXl: 12;
|
|
31
|
+
readonly radius2xl: 16;
|
|
32
|
+
readonly radiusFull: 9999;
|
|
33
|
+
readonly iconXs: 12;
|
|
34
|
+
readonly iconSm: 16;
|
|
35
|
+
readonly iconMd: 24;
|
|
36
|
+
readonly iconLg: 32;
|
|
37
|
+
readonly iconXl: 48;
|
|
38
|
+
};
|
|
39
|
+
export declare const base: 8, xxs: 2, xs: 4, sm: 8, md: 16, lg: 24, xl: 32, xxl: 48, xxxl: 64, gutter: 16, gutterVertical: 24, screenPadding: 16, buttonPadding: 10, inputPadding: 10, cardPadding: 16, sectionSpacing: 32, listItemSpacing: 8, radiusNone: 0, radiusXs: 2, radiusSm: 4, radiusMd: 6, radiusLg: 8, radiusXl: 12, radius2xl: 16, radiusFull: 9999, iconXs: 12, iconSm: 16, iconMd: 24, iconLg: 32, iconXl: 48;
|
|
40
|
+
export declare const space: (multiplier: number) => number;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spacing Constants
|
|
3
|
+
*
|
|
4
|
+
* A consistent spacing scale based on an 8px base unit.
|
|
5
|
+
* Use these constants throughout the app for consistent spacing.
|
|
6
|
+
*/
|
|
7
|
+
export const spacing = {
|
|
8
|
+
// Base unit: 8px
|
|
9
|
+
base: 8,
|
|
10
|
+
// Spacing scale
|
|
11
|
+
xxs: 2, // 2px - Minimal spacing
|
|
12
|
+
xs: 4, // 4px - Extra small
|
|
13
|
+
sm: 8, // 8px - Small (1 unit)
|
|
14
|
+
md: 16, // 16px - Medium (2 units)
|
|
15
|
+
lg: 24, // 24px - Large (3 units)
|
|
16
|
+
xl: 32, // 32px - Extra large (4 units)
|
|
17
|
+
xxl: 48, // 48px - 2x extra large (6 units)
|
|
18
|
+
xxxl: 64, // 64px - 3x extra large (8 units)
|
|
19
|
+
// Common layout spacing
|
|
20
|
+
gutter: 16, // Standard horizontal gutter
|
|
21
|
+
gutterVertical: 24, // Standard vertical spacing
|
|
22
|
+
screenPadding: 16, // Default screen edge padding
|
|
23
|
+
// Component-specific
|
|
24
|
+
buttonPadding: 10, // Default button padding
|
|
25
|
+
inputPadding: 10, // Default input padding
|
|
26
|
+
cardPadding: 16, // Default card padding
|
|
27
|
+
sectionSpacing: 32, // Space between major sections
|
|
28
|
+
listItemSpacing: 8, // Space between list items
|
|
29
|
+
// Border radius — shadcn-inspired scale (radiusMd = 6px default)
|
|
30
|
+
radiusNone: 0,
|
|
31
|
+
radiusXs: 2,
|
|
32
|
+
radiusSm: 4,
|
|
33
|
+
radiusMd: 6,
|
|
34
|
+
radiusLg: 8,
|
|
35
|
+
radiusXl: 12,
|
|
36
|
+
radius2xl: 16,
|
|
37
|
+
radiusFull: 9999, // For circular elements
|
|
38
|
+
// Icon sizes
|
|
39
|
+
iconXs: 12,
|
|
40
|
+
iconSm: 16,
|
|
41
|
+
iconMd: 24,
|
|
42
|
+
iconLg: 32,
|
|
43
|
+
iconXl: 48,
|
|
44
|
+
};
|
|
45
|
+
// Export individual constants for convenience
|
|
46
|
+
export const { base, xxs, xs, sm, md, lg, xl, xxl, xxxl, gutter, gutterVertical, screenPadding, buttonPadding, inputPadding, cardPadding, sectionSpacing, listItemSpacing, radiusNone, radiusXs, radiusSm, radiusMd, radiusLg, radiusXl, radius2xl, radiusFull, iconXs, iconSm, iconMd, iconLg, iconXl, } = spacing;
|
|
47
|
+
// Helper function to multiply base spacing
|
|
48
|
+
export const space = (multiplier) => spacing.base * multiplier;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const SCREEN_SIZES: {
|
|
2
|
+
readonly SMALL: 768;
|
|
3
|
+
readonly MEDIUM: 1000;
|
|
4
|
+
readonly LARGE: 1200;
|
|
5
|
+
};
|
|
6
|
+
type WindowDimensions = {
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
orientation: "landscape" | "portrait";
|
|
10
|
+
isSmallScreen: boolean;
|
|
11
|
+
isMediumScreen: boolean;
|
|
12
|
+
isLargeScreen: boolean;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Provides a consistent way to access window dimensions and screen size information across mobile and web.
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
export declare const useDimensions: () => WindowDimensions;
|
|
19
|
+
export {};
|