@mrmeg/expo-ui 0.1.6 → 0.1.7

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/LLM_USAGE.md CHANGED
@@ -119,10 +119,25 @@ Token intent:
119
119
  - `ring`: focus outline color
120
120
  - `popover`: elevated overlay surface
121
121
 
122
- Use `getShadowStyle()` for package surfaces that need elevation and
123
- `getFocusRingStyle()` for web focus styling. Keep web controls compact, but
124
- preserve mobile tap comfort with package controls that already provide native
125
- hit slop or 44px touch rows.
122
+ Use `getShadowStyle()` for package surfaces that need elevation. It supports
123
+ `base`, `soft`, `sharp`, `subtle`, `elevated`, `glow`, `glass`, `card`,
124
+ `cardHover`, and `cardSubtle`, returning native shadow/elevation off web and
125
+ CSS `boxShadow` on web. Use `getFocusRingStyle()` for web focus styling. Keep
126
+ web controls compact, but preserve mobile tap comfort with package controls
127
+ that already provide native hit slop or 44px touch rows.
128
+
129
+ Use `useStyles()` for memoized theme-aware local styles. Its factory receives
130
+ `{ theme, spacing, withAlpha }`, so components can derive alpha-adjusted
131
+ semantic colors without destructuring `withAlpha` outside the factory:
132
+
133
+ ```tsx
134
+ const { styles } = useStyles(({ theme, spacing, withAlpha }) => ({
135
+ card: {
136
+ backgroundColor: withAlpha(theme.colors.primary, 0.08),
137
+ padding: spacing.md,
138
+ },
139
+ }));
140
+ ```
126
141
 
127
142
  ## Component Use-Case Index
128
143
 
package/README.md CHANGED
@@ -95,7 +95,21 @@ const styles = StyleSheet.create({
95
95
  });
96
96
  ```
97
97
 
98
- `useTheme()` returns the active `theme`, resolved `scheme`, persisted `currentTheme`, `setTheme`, `toggleTheme`, cross-platform shadow helpers, a web focus-ring helper, contrast helpers, and `withAlpha`. Use semantic tokens such as `theme.colors.background`, `foreground`, `card`, `popover`, `border`, `input`, `ring`, `primary`, `secondary`, `accent`, `mutedForeground`, `destructive`, `success`, and `warning`. `primary` is the neutral action color, `secondary` is a neutral secondary surface, `accent` is the teal highlight color, `input` is the default form-control border, and `ring` is the focus outline color.
98
+ `useTheme()` returns the active `theme`, resolved `scheme`, persisted `currentTheme`, `setTheme`, `toggleTheme`, cross-platform shadow helpers, a web focus-ring helper, contrast helpers, and `withAlpha`. `getShadowStyle(type)` supports `base`, `soft`, `sharp`, `subtle`, `elevated`, `glow`, `glass`, `card`, `cardHover`, and `cardSubtle`. Use semantic tokens such as `theme.colors.background`, `foreground`, `card`, `popover`, `border`, `input`, `ring`, `primary`, `secondary`, `accent`, `mutedForeground`, `destructive`, `success`, and `warning`. `primary` is the neutral action color, `secondary` is a neutral secondary surface, `accent` is the teal highlight color, `input` is the default form-control border, and `ring` is the focus outline color.
99
+
100
+ Use `useStyles()` when a component needs memoized theme-aware styles. The style factory receives `{ theme, spacing, withAlpha }`, and the returned hook value also includes the normal `useTheme()` helpers.
101
+
102
+ ```tsx
103
+ import { useStyles } from "@mrmeg/expo-ui/hooks";
104
+
105
+ const { styles } = useStyles(({ theme, spacing, withAlpha }) => ({
106
+ card: {
107
+ backgroundColor: withAlpha(theme.colors.primary, 0.08),
108
+ borderRadius: spacing.radiusMd,
109
+ padding: spacing.md,
110
+ },
111
+ }));
112
+ ```
99
113
 
100
114
  Use `StyledText` for theme-aware text:
101
115
 
@@ -1,7 +1,7 @@
1
1
  import { Colors } from "../constants/colors";
2
2
  import { ViewStyle, StyleSheet } from "react-native";
3
3
  import { spacing as spacingConstants } from "../constants/spacing";
4
- type ShadowType = "base" | "soft" | "sharp" | "subtle";
4
+ type ShadowType = "base" | "soft" | "sharp" | "subtle" | "elevated" | "glow" | "glass" | "card" | "cardHover" | "cardSubtle";
5
5
  interface ExtendedColorScheme {
6
6
  theme: Colors["light" | "dark"];
7
7
  scheme: "light" | "dark";
@@ -45,6 +45,7 @@ export declare function useTheme(): ExtendedColorScheme & {
45
45
  interface StyleContext {
46
46
  theme: Colors["light" | "dark"];
47
47
  spacing: typeof spacingConstants;
48
+ withAlpha: (color: string, alpha: number) => string;
48
49
  }
49
50
  /**
50
51
  * Return type for useStyles hook
@@ -58,17 +59,17 @@ type UseStylesReturn<T extends StyleSheet.NamedStyles<T>> = {
58
59
  * useStyles
59
60
  *
60
61
  * A hook that combines useTheme with StyleSheet.create for theme-aware styling.
61
- * Provides access to theme colors and spacing constants within the style factory.
62
+ * Provides access to theme colors, spacing constants, and color helpers within the style factory.
62
63
  *
63
- * @param factory - A function that receives { theme, spacing } and returns style definitions
64
+ * @param factory - A function that receives { theme, spacing, withAlpha } and returns style definitions
64
65
  * @returns { styles, theme, spacing, ...themeUtilities }
65
66
  *
66
67
  * @example
67
68
  * ```tsx
68
69
  * function MyComponent() {
69
- * const { styles, theme } = useStyles(({ theme, spacing }) => ({
70
+ * const { styles, theme } = useStyles(({ theme, spacing, withAlpha }) => ({
70
71
  * container: {
71
- * backgroundColor: theme.colors.background,
72
+ * backgroundColor: withAlpha(theme.colors.primary, 0.08),
72
73
  * padding: spacing.md,
73
74
  * borderRadius: spacing.radiusMd,
74
75
  * },
@@ -109,6 +109,48 @@ export function useTheme() {
109
109
  shadowRadius: 2,
110
110
  elevation: 1,
111
111
  },
112
+ elevated: {
113
+ shadowColor: theme.colors.overlay,
114
+ shadowOffset: { width: 0, height: 20 },
115
+ shadowOpacity: 0.15,
116
+ shadowRadius: 40,
117
+ elevation: 16,
118
+ },
119
+ glow: {
120
+ shadowColor: theme.colors.primary,
121
+ shadowOffset: { width: 0, height: 4 },
122
+ shadowOpacity: 0.4,
123
+ shadowRadius: 20,
124
+ elevation: 10,
125
+ },
126
+ glass: {
127
+ shadowColor: theme.colors.overlay,
128
+ shadowOffset: { width: 0, height: 4 },
129
+ shadowOpacity: 0.05,
130
+ shadowRadius: 30,
131
+ elevation: 4,
132
+ },
133
+ card: {
134
+ shadowColor: theme.colors.overlay,
135
+ shadowOffset: { width: 0, height: 2 },
136
+ shadowOpacity: 0.08,
137
+ shadowRadius: 8,
138
+ elevation: 4,
139
+ },
140
+ cardHover: {
141
+ shadowColor: theme.colors.overlay,
142
+ shadowOffset: { width: 0, height: 8 },
143
+ shadowOpacity: 0.12,
144
+ shadowRadius: 24,
145
+ elevation: 8,
146
+ },
147
+ cardSubtle: {
148
+ shadowColor: theme.colors.overlay,
149
+ shadowOffset: { width: 0, height: 1 },
150
+ shadowOpacity: 0.08,
151
+ shadowRadius: 3,
152
+ elevation: 2,
153
+ },
112
154
  };
113
155
  const config = shadowConfigs[type];
114
156
  if (Platform.OS === "web") {
@@ -117,6 +159,12 @@ export function useTheme() {
117
159
  soft: { boxShadow: theme.dark ? "0 8px 24px rgba(0, 0, 0, 0.36)" : "0 8px 24px rgba(0, 0, 0, 0.10)" },
118
160
  sharp: { boxShadow: theme.dark ? "0 1px 1px rgba(0, 0, 0, 0.55)" : "0 1px 1px rgba(0, 0, 0, 0.12)" },
119
161
  subtle: { boxShadow: theme.dark ? "0 1px 2px rgba(0, 0, 0, 0.32)" : "0 1px 2px rgba(0, 0, 0, 0.05)" },
162
+ elevated: { boxShadow: theme.dark ? "0 20px 40px rgba(0, 0, 0, 0.38)" : "0 20px 40px rgba(0, 0, 0, 0.15)" },
163
+ glow: { boxShadow: `0 0 20px ${theme.colors.primary}` },
164
+ glass: { boxShadow: theme.dark ? "0 4px 30px rgba(0, 0, 0, 0.32)" : "0 4px 30px rgba(0, 0, 0, 0.05)" },
165
+ card: { boxShadow: theme.dark ? "0 1px 2px rgba(0, 0, 0, 0.32)" : "0 1px 3px rgba(0, 0, 0, 0.08)" },
166
+ cardHover: { boxShadow: theme.dark ? "0 8px 24px rgba(0, 0, 0, 0.36)" : "0 8px 24px rgba(0, 0, 0, 0.12)" },
167
+ cardSubtle: { boxShadow: theme.dark ? "0 1px 2px rgba(0, 0, 0, 0.32)" : "0 1px 3px rgba(0, 0, 0, 0.05)" },
120
168
  };
121
169
  return webShadows[type];
122
170
  }
@@ -304,17 +352,17 @@ function withAlpha(color, alpha) {
304
352
  * useStyles
305
353
  *
306
354
  * A hook that combines useTheme with StyleSheet.create for theme-aware styling.
307
- * Provides access to theme colors and spacing constants within the style factory.
355
+ * Provides access to theme colors, spacing constants, and color helpers within the style factory.
308
356
  *
309
- * @param factory - A function that receives { theme, spacing } and returns style definitions
357
+ * @param factory - A function that receives { theme, spacing, withAlpha } and returns style definitions
310
358
  * @returns { styles, theme, spacing, ...themeUtilities }
311
359
  *
312
360
  * @example
313
361
  * ```tsx
314
362
  * function MyComponent() {
315
- * const { styles, theme } = useStyles(({ theme, spacing }) => ({
363
+ * const { styles, theme } = useStyles(({ theme, spacing, withAlpha }) => ({
316
364
  * container: {
317
- * backgroundColor: theme.colors.background,
365
+ * backgroundColor: withAlpha(theme.colors.primary, 0.08),
318
366
  * padding: spacing.md,
319
367
  * borderRadius: spacing.radiusMd,
320
368
  * },
@@ -337,7 +385,8 @@ export function useStyles(factory) {
337
385
  const styles = useMemo(() => StyleSheet.create(factory({
338
386
  theme: themeContext.theme,
339
387
  spacing: spacingConstants,
340
- })), [factory, themeContext.theme]);
388
+ withAlpha: themeContext.withAlpha,
389
+ })), [factory, themeContext.theme, themeContext.withAlpha]);
341
390
  return useMemo(() => ({
342
391
  styles,
343
392
  theme: themeContext.theme,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrmeg/expo-ui",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "private": false,
5
5
  "description": "Reusable Expo and React Native UI primitives for MrMeg projects.",
6
6
  "keywords": [