@namiml/expo-sdk 3.4.6-dev.202607170209 → 3.4.6-dev.202607171421

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": "@namiml/expo-sdk",
3
- "version": "3.4.6-dev.202607170209",
3
+ "version": "3.4.6-dev.202607171421",
4
4
  "type": "module",
5
5
  "description": "Nami Expo SDK — paywall and subscription management for Expo apps",
6
6
  "main": "./dist/index.cjs",
@@ -29,8 +29,8 @@
29
29
  "prepublishOnly": "yarn clean && yarn build:prod"
30
30
  },
31
31
  "dependencies": {
32
- "@namiml/expo-nami-iap": "3.4.6-dev.202607170209",
33
- "@namiml/sdk-core": "3.4.6-dev.202607170209",
32
+ "@namiml/expo-nami-iap": "3.4.6-dev.202607171421",
33
+ "@namiml/sdk-core": "3.4.6-dev.202607171421",
34
34
  "react-native-qrcode-svg": "^6.3.21",
35
35
  "react-native-safe-area-context": "^5.6.0",
36
36
  "react-native-svg": "^15.15.4"
@@ -2,6 +2,7 @@ import React, { useCallback, useMemo, useRef, useState } from 'react';
2
2
  import { View, Pressable, Animated } from 'react-native';
3
3
  import { useFirstFocusReadyContext, usePaywallContext } from '../../context/PaywallContext';
4
4
  import { applyStyles, childSpacingStyle, focusedStyleOverrides, parseSizeOrPercent } from '../../utils/styles';
5
+ import { collapseHeaderA11yProps, collapseBodyA11yProps } from '../../utils/rendering';
5
6
  import { TemplateRenderer } from '../TemplateRenderer';
6
7
  import type { TComponent, TCollapseContainer } from '@namiml/sdk-core';
7
8
  import { FocusedStyleProvider, FocusScope, useFocusableState, useFocusEnabled, useRegisterPreferredFocus } from '../../context/FocusContext';
@@ -96,13 +97,17 @@ export const NamiCollapseContainer: React.FC<Props> = ({ component, scaleFactor,
96
97
  onFocus={handleFocus}
97
98
  onBlur={onBlur}
98
99
  hasTVPreferredFocus={focusEnabled && initialFocus}
100
+ {...collapseHeaderA11yProps(isOpen)}
99
101
  style={({ pressed }) => [{ opacity: pressed ? 0.7 : 1 }]}
100
102
  >
101
103
  {headerContainer ? (
102
104
  <TemplateRenderer component={headerContainer as any} scaleFactor={scaleFactor} onClose={onClose} parentDirection={direction} />
103
105
  ) : null}
104
106
  </Pressable>
105
- <Animated.View style={[{ maxHeight, overflow: 'hidden' }, bodySizeStyle, headerSpacing]}>
107
+ <Animated.View
108
+ {...collapseBodyA11yProps(isOpen)}
109
+ style={[{ maxHeight, overflow: 'hidden' }, bodySizeStyle, headerSpacing]}
110
+ >
106
111
  {bodyComponents.map((child: TComponent, i: number) => (
107
112
  <View key={child.id ?? i} style={childSpacingStyle(i, { spacing: component.spacing, direction: component.direction }, scaleFactor)}>
108
113
  <TemplateRenderer component={child} scaleFactor={scaleFactor} onClose={onClose} parentDirection={direction} />
@@ -214,6 +214,28 @@ export function getRepeatingListBlocks(ctx: any, component: any): TComponent[][]
214
214
  return result;
215
215
  }
216
216
 
217
+ /**
218
+ * Accessibility props for a collapse container's trigger (NAM-2528): a button
219
+ * whose expanded/collapsed state is announced by VoiceOver/TalkBack.
220
+ */
221
+ export function collapseHeaderA11yProps(isOpen: boolean) {
222
+ return {
223
+ accessibilityRole: 'button' as const,
224
+ accessibilityState: { expanded: isOpen },
225
+ };
226
+ }
227
+
228
+ /**
229
+ * Accessibility props for a collapse container's body, which stays mounted at
230
+ * maxHeight 0 while collapsed and must be hidden from assistive tech then.
231
+ */
232
+ export function collapseBodyA11yProps(isOpen: boolean) {
233
+ return {
234
+ accessibilityElementsHidden: !isOpen,
235
+ importantForAccessibility: (isOpen ? 'auto' : 'no-hide-descendants') as 'auto' | 'no-hide-descendants',
236
+ };
237
+ }
238
+
217
239
  function testObjectMatches(
218
240
  ctx: any,
219
241
  { value: rawValue, expected, operator }: { value: any; expected: any; operator: string },