@idealyst/components 1.2.44 → 1.2.46

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idealyst/components",
3
- "version": "1.2.44",
3
+ "version": "1.2.46",
4
4
  "description": "Shared component library for React and React Native",
5
5
  "documentation": "https://github.com/IdealystIO/idealyst-framework/tree/main/packages/components#readme",
6
6
  "readme": "README.md",
@@ -56,7 +56,7 @@
56
56
  "publish:npm": "npm publish"
57
57
  },
58
58
  "peerDependencies": {
59
- "@idealyst/theme": "^1.2.44",
59
+ "@idealyst/theme": "^1.2.46",
60
60
  "@mdi/js": ">=7.0.0",
61
61
  "@mdi/react": ">=1.0.0",
62
62
  "@react-native-vector-icons/common": ">=12.0.0",
@@ -107,7 +107,7 @@
107
107
  },
108
108
  "devDependencies": {
109
109
  "@idealyst/blur": "^1.2.40",
110
- "@idealyst/theme": "^1.2.44",
110
+ "@idealyst/theme": "^1.2.46",
111
111
  "@idealyst/tooling": "^1.2.30",
112
112
  "@mdi/react": "^1.6.1",
113
113
  "@types/react": "^19.1.0",
@@ -127,7 +127,6 @@ export const dialogStyles = defineStyle('Dialog', (theme: Theme) => ({
127
127
  }),
128
128
 
129
129
  content: (_props: DialogDynamicProps) => ({
130
- padding: 24,
131
130
  _web: {
132
131
  overflow: 'visible',
133
132
  maxHeight: 'none',
@@ -34,6 +34,10 @@ export const IconSvg: React.FC<IconSvgProps> = ({
34
34
  // Look up path from registry
35
35
  const path = IconRegistry.get(name);
36
36
 
37
+ // Convert numeric size to pixel string to prevent @mdi/react from
38
+ // treating it as a multiplier of the base 24px size
39
+ const normalizedSize = typeof size === 'number' ? `${size}px` : size;
40
+
37
41
  // Warn in development if icon is not registered
38
42
  if (!path && process.env.NODE_ENV !== 'production') {
39
43
  console.warn(
@@ -51,7 +55,7 @@ export const IconSvg: React.FC<IconSvgProps> = ({
51
55
  style={style}
52
56
  className={className}
53
57
  path={path}
54
- size={size}
58
+ size={normalizedSize}
55
59
  color={color}
56
60
  aria-label={ariaLabel || name}
57
61
  data-testid={testID}
@@ -1,5 +1,6 @@
1
- import { forwardRef } from 'react';
2
- import { View as RNView, ScrollView as RNScrollView, KeyboardAvoidingView, Platform } from 'react-native';
1
+ import { forwardRef, useEffect } from 'react';
2
+ import { View as RNView, ScrollView as RNScrollView, Keyboard, Platform } from 'react-native';
3
+ import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated';
3
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
5
  import { ScreenProps } from './types';
5
6
  import { screenStyles } from './Screen.styles';
@@ -27,6 +28,40 @@ const Screen = forwardRef<IdealystElement, ScreenProps>(({
27
28
  }, ref) => {
28
29
  const insets = useSafeAreaInsets();
29
30
 
31
+ // Animated keyboard offset
32
+ const keyboardOffset = useSharedValue(0);
33
+
34
+ // Listen for keyboard events and animate
35
+ useEffect(() => {
36
+ if (!avoidKeyboard) return;
37
+
38
+ const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
39
+ const hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
40
+
41
+ const showSubscription = Keyboard.addListener(showEvent, (e) => {
42
+ keyboardOffset.value = withTiming(e.endCoordinates.height, {
43
+ duration: Platform.OS === 'ios' ? e.duration : 250,
44
+ easing: Easing.out(Easing.cubic),
45
+ });
46
+ });
47
+
48
+ const hideSubscription = Keyboard.addListener(hideEvent, (e) => {
49
+ keyboardOffset.value = withTiming(0, {
50
+ duration: Platform.OS === 'ios' ? (e.duration ?? 250) : 250,
51
+ easing: Easing.out(Easing.cubic),
52
+ });
53
+ });
54
+
55
+ return () => {
56
+ showSubscription.remove();
57
+ hideSubscription.remove();
58
+ };
59
+ }, [avoidKeyboard]);
60
+
61
+ const animatedKeyboardStyle = useAnimatedStyle(() => ({
62
+ paddingBottom: keyboardOffset.value,
63
+ }));
64
+
30
65
  // Handle 'transparent' background separately since it's not a surface color key
31
66
  // The $surface iterator only expands to actual surface color keys
32
67
  const backgroundVariant = background === 'transparent' ? undefined : background;
@@ -55,13 +90,6 @@ const Screen = forwardRef<IdealystElement, ScreenProps>(({
55
90
  paddingRight: insets.right,
56
91
  } : undefined;
57
92
 
58
- // Wrapper component for keyboard avoidance
59
- const KeyboardWrapper = avoidKeyboard ? KeyboardAvoidingView : RNView;
60
- const keyboardWrapperProps = avoidKeyboard ? {
61
- behavior: Platform.OS === 'ios' ? 'padding' as const : 'height' as const,
62
- style: { flex: 1 },
63
- } : { style: { flex: 1 } };
64
-
65
93
  if (scrollable) {
66
94
  // Content styles applied via View wrapper for Unistyles reactivity
67
95
  // (contentContainerStyle isn't reactive, only style prop is)
@@ -73,7 +101,7 @@ const Screen = forwardRef<IdealystElement, ScreenProps>(({
73
101
  } : safeAreaStyle;
74
102
 
75
103
  return (
76
- <KeyboardWrapper {...keyboardWrapperProps}>
104
+ <Animated.View style={[{ flex: 1 }, avoidKeyboard && animatedKeyboardStyle]}>
77
105
  <RNScrollView
78
106
  ref={ref as any}
79
107
  nativeID={id}
@@ -87,16 +115,16 @@ const Screen = forwardRef<IdealystElement, ScreenProps>(({
87
115
  {children}
88
116
  </RNView>
89
117
  </RNScrollView>
90
- </KeyboardWrapper>
118
+ </Animated.View>
91
119
  );
92
120
  }
93
121
 
94
122
  return (
95
- <KeyboardWrapper {...keyboardWrapperProps}>
123
+ <Animated.View style={[{ flex: 1 }, avoidKeyboard && animatedKeyboardStyle]}>
96
124
  <RNView ref={ref as any} nativeID={id} style={[screenStyle, safeAreaStyle, style]} testID={testID} onLayout={onLayout}>
97
125
  {children}
98
126
  </RNView>
99
- </KeyboardWrapper>
127
+ </Animated.View>
100
128
  );
101
129
  });
102
130
 
@@ -68,6 +68,7 @@ export const textAreaStyles = defineStyle('TextArea', (theme: Theme) => ({
68
68
 
69
69
  textareaContainer: (_props: TextAreaVariants) => ({
70
70
  position: 'relative' as const,
71
+ width: '100%',
71
72
  borderWidth: 1,
72
73
  borderColor: theme.colors.border.primary,
73
74
  borderRadius: theme.radii.md,
@@ -80,6 +81,7 @@ export const textAreaStyles = defineStyle('TextArea', (theme: Theme) => ({
80
81
  },
81
82
  },
82
83
  _web: {
84
+ boxSizing: 'border-box',
83
85
  border: `1px solid ${theme.colors.border.primary}`,
84
86
  },
85
87
  }),
@@ -112,9 +114,13 @@ export const textAreaStyles = defineStyle('TextArea', (theme: Theme) => ({
112
114
  },
113
115
  },
114
116
  _web: {
117
+ display: 'block',
118
+ width: '100%',
115
119
  fontFamily: 'inherit',
116
120
  outline: 'none',
117
121
  border: 'none',
122
+ borderWidth: 0,
123
+ background: 'transparent',
118
124
  transition: 'border-color 0.2s ease, box-shadow 0.2s ease',
119
125
  boxSizing: 'border-box',
120
126
  overflowY: 'hidden',