@idealyst/components 1.2.15 → 1.2.17

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.15",
3
+ "version": "1.2.17",
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.15",
59
+ "@idealyst/theme": "^1.2.17",
60
60
  "@mdi/js": ">=7.0.0",
61
61
  "@mdi/react": ">=1.0.0",
62
62
  "@react-native-vector-icons/common": ">=12.0.0",
@@ -106,7 +106,7 @@
106
106
  }
107
107
  },
108
108
  "devDependencies": {
109
- "@idealyst/theme": "^1.2.15",
109
+ "@idealyst/theme": "^1.2.17",
110
110
  "@idealyst/tooling": "^1.2.4",
111
111
  "@mdi/react": "^1.6.1",
112
112
  "@types/react": "^19.1.0",
@@ -92,4 +92,15 @@ export const viewStyles = defineStyle('View', (theme: Theme) => ({
92
92
  boxSizing: 'border-box',
93
93
  },
94
94
  }),
95
+ // Web-only: Wrapper for scrollable view
96
+ scrollableWrapper: {
97
+ _web: {
98
+ display: 'flex',
99
+ flexDirection: 'column',
100
+ flex: 1,
101
+ position: 'relative',
102
+ boxSizing: 'border-box',
103
+ minHeight: 0, // Important for flex children to allow shrinking
104
+ },
105
+ },
95
106
  }));
@@ -47,6 +47,8 @@ const View = forwardRef<HTMLDivElement, ViewProps>(({
47
47
  // Call style as function to get theme-reactive styles
48
48
  /** @ts-ignore */
49
49
  const webProps = getWebProps((viewStyles.view as any)({}));
50
+ /** @ts-ignore */
51
+ const wrapperWebProps = getWebProps(viewStyles.scrollableWrapper);
50
52
 
51
53
  const mergedRef = useMergeRefs(ref, webProps.ref);
52
54
 
@@ -54,7 +56,7 @@ const View = forwardRef<HTMLDivElement, ViewProps>(({
54
56
  // Wrapper: sizing and margin (positioning in parent layout)
55
57
  // Content: absolutely positioned with overflow:auto, visual styles (padding, background, border)
56
58
  if (scrollable) {
57
- // Extract layout/sizing styles for the wrapper, visual styles go to content
59
+ // Split user styles: layout/sizing to wrapper, visual styles to content
58
60
  const styleObj = (style as React.CSSProperties) || {};
59
61
  const {
60
62
  // Sizing - goes to wrapper
@@ -82,47 +84,47 @@ const View = forwardRef<HTMLDivElement, ViewProps>(({
82
84
  ...contentStyles
83
85
  } = styleObj;
84
86
 
85
- const wrapperStyles: React.CSSProperties = {
86
- position: 'relative',
87
- boxSizing: 'border-box',
88
- // If no explicit sizing, flex-grow to fill remaining space
89
- ...(width === undefined && height === undefined && flex === undefined && { flex: 1 }),
90
- // Apply sizing
91
- width,
92
- height,
93
- minWidth,
94
- minHeight: minHeight ?? 0, // Important for flex children to allow shrinking
95
- maxWidth,
96
- maxHeight,
97
- // Apply flex properties
98
- flex,
99
- flexGrow,
100
- flexShrink,
101
- flexBasis,
102
- alignSelf,
103
- // Apply margin
104
- margin,
105
- marginTop,
106
- marginRight,
107
- marginBottom,
108
- marginLeft,
109
- marginBlock,
110
- marginInline,
87
+ // Determine flex behavior:
88
+ // - If explicit flex is provided, use it
89
+ // - If explicit width/height are provided (without flex), disable flex
90
+ // - Otherwise, let Unistyles' flex:1 apply
91
+ const hasExplicitSize = width !== undefined || height !== undefined;
92
+ const flexValue = flex !== undefined ? flex : (hasExplicitSize ? 'none' : undefined);
93
+
94
+ // Only include defined values in wrapper styles
95
+ const wrapperUserStyles: React.CSSProperties = {
96
+ ...(width !== undefined && { width }),
97
+ ...(height !== undefined && { height }),
98
+ ...(minWidth !== undefined && { minWidth }),
99
+ ...(minHeight !== undefined && { minHeight }),
100
+ ...(maxWidth !== undefined && { maxWidth }),
101
+ ...(maxHeight !== undefined && { maxHeight }),
102
+ ...(flexValue !== undefined && { flex: flexValue }),
103
+ ...(flexGrow !== undefined && { flexGrow }),
104
+ ...(flexShrink !== undefined && { flexShrink }),
105
+ ...(flexBasis !== undefined && { flexBasis }),
106
+ ...(alignSelf !== undefined && { alignSelf }),
107
+ ...(margin !== undefined && { margin }),
108
+ ...(marginTop !== undefined && { marginTop }),
109
+ ...(marginRight !== undefined && { marginRight }),
110
+ ...(marginBottom !== undefined && { marginBottom }),
111
+ ...(marginLeft !== undefined && { marginLeft }),
112
+ ...(marginBlock !== undefined && { marginBlock }),
113
+ ...(marginInline !== undefined && { marginInline }),
111
114
  };
112
115
 
113
116
  return (
114
- <div style={wrapperStyles}>
117
+ <div {...wrapperWebProps} style={wrapperUserStyles}>
115
118
  <div
116
119
  {...webProps}
117
120
  style={{
118
- // Content is block (not flex) for natural scrolling behavior
121
+ // Critical: these must override webProps' display:flex
119
122
  display: 'block',
120
- // Absolutely positioned to fill wrapper
121
123
  position: 'absolute',
122
124
  inset: 0,
123
125
  overflow: 'auto',
124
126
  boxSizing: 'border-box',
125
- // Apply visual styles (padding, background, border, etc.)
127
+ // User's visual styles
126
128
  ...contentStyles,
127
129
  }}
128
130
  ref={mergedRef}
@@ -165,6 +165,50 @@ export const ViewExamples = () => {
165
165
  </View>
166
166
  </View>
167
167
  </View>
168
+
169
+ {/* Scrollable with Flex Example */}
170
+ <View gap="md">
171
+ <Text typography="subtitle1">Scrollable with Flex</Text>
172
+ <Text typography="body2" color="secondary">
173
+ 200x300px container with 100px header and flex:1 scrollable area
174
+ </Text>
175
+ <View
176
+ border="thin"
177
+ radius="md"
178
+ style={{ width: 200, height: 300 }}
179
+ >
180
+ {/* Fixed 100px header */}
181
+ <View
182
+ background="tertiary"
183
+ padding="sm"
184
+ style={{ height: 100, justifyContent: 'center', alignItems: 'center' }}
185
+ >
186
+ <Text typography="subtitle2">Header (100px)</Text>
187
+ </View>
188
+ {/* Flex scrollable content */}
189
+ <View
190
+ scrollable
191
+ background="secondary"
192
+ padding="md"
193
+ style={{ flex: 1 }}
194
+ >
195
+ <View>
196
+ <Text typography="body2">Scrollable content below header</Text>
197
+ <Text typography="body2">Line 2</Text>
198
+ <Text typography="body2">Line 3</Text>
199
+ <Text typography="body2">Line 4</Text>
200
+ <Text typography="body2">Line 5</Text>
201
+ <Text typography="body2">Line 6</Text>
202
+ <Text typography="body2">Line 7</Text>
203
+ <Text typography="body2">Line 8</Text>
204
+ <Text typography="body2">Line 9</Text>
205
+ <Text typography="body2">Line 10</Text>
206
+ <Text typography="body2">Line 11</Text>
207
+ <Text typography="body2">Line 12: End</Text>
208
+ </View>
209
+ </View>
210
+ </View>
211
+ </View>
168
212
  </View>
169
213
  </Screen>
170
214
  );