@applicaster/zapp-react-native-ui-components 13.0.6-rc.0 → 13.0.7-alpha.2991546311

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.
@@ -15,6 +15,7 @@ import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUt
15
15
  import { styles } from "./styles";
16
16
 
17
17
  type Props = {
18
+ dataLength: number;
18
19
  item: ZappEntry;
19
20
  index: number;
20
21
  shouldScrollHorizontally: (arg1: [any]) => boolean | null | undefined;
@@ -70,6 +71,8 @@ type State = {
70
71
  };
71
72
 
72
73
  export class CellComponent extends React.Component<Props, State> {
74
+ accessibilityManager: AccessibilityManager;
75
+
73
76
  constructor(props) {
74
77
  super(props);
75
78
  this.onPress = this.onPress.bind(this);
@@ -79,10 +82,13 @@ export class CellComponent extends React.Component<Props, State> {
79
82
  this.hasReceivedFocus = this.hasReceivedFocus.bind(this);
80
83
  this.scrollVertically = this.scrollVertically.bind(this);
81
84
  this.scrollToIndex = this.scrollToIndex.bind(this);
85
+ this.handleAccessibilityFocus = this.handleAccessibilityFocus.bind(this);
82
86
 
83
87
  this.state = {
84
88
  hasFocusableInside: props.CellRenderer.hasFocusableInside?.(props.item),
85
89
  };
90
+
91
+ this.accessibilityManager = AccessibilityManager.getInstance();
86
92
  }
87
93
 
88
94
  setScreenLayout(componentAnchorPointY, screenLayout) {
@@ -183,6 +189,24 @@ export class CellComponent extends React.Component<Props, State> {
183
189
  return !isFocusable ? false : focused || focusableFocused;
184
190
  }
185
191
 
192
+ handleAccessibilityFocus(item, index, dataLength) {
193
+ const accessibilityTitle =
194
+ item?.extensions?.accessibility?.label || item?.title || "";
195
+
196
+ const accessibilityHint = item?.extensions?.accessibility?.hint || "";
197
+
198
+ // For loop scrolling, calculate the correct logical index
199
+ const logicalIndex = dataLength ? index % dataLength : index;
200
+
201
+ const positionLabel = dataLength
202
+ ? `item ${logicalIndex + 1} of ${dataLength}`
203
+ : "";
204
+
205
+ this.accessibilityManager.readText({
206
+ text: `${accessibilityTitle} ${accessibilityHint} ${positionLabel}`,
207
+ });
208
+ }
209
+
186
210
  componentDidUpdate(prevProps: Readonly<Props>) {
187
211
  if (prevProps.item !== this.props.item) {
188
212
  this.setState({
@@ -197,6 +221,7 @@ export class CellComponent extends React.Component<Props, State> {
197
221
  const {
198
222
  item,
199
223
  index,
224
+ dataLength,
200
225
  component,
201
226
  offsetUpdater,
202
227
  preferredFocus,
@@ -257,22 +282,15 @@ export class CellComponent extends React.Component<Props, State> {
257
282
  style={styles.baseCell}
258
283
  isFocusable={isFocusable}
259
284
  skipFocusManagerRegistration={skipFocusManagerRegistration}
285
+ {...this.accessibilityManager.getButtonAccessibilityProps(
286
+ item?.extensions?.accessibility?.label || item?.title
287
+ )}
260
288
  >
261
289
  {(focused, event) => {
262
290
  const isFocused = this.isCellFocused(focused);
263
291
 
264
292
  if (isFocused) {
265
- const accessibilityManager = AccessibilityManager.getInstance();
266
-
267
- const accessibilityTitle =
268
- item?.extensions?.accessibility?.label || item?.title || "";
269
-
270
- const accessibilityHint =
271
- item?.extensions?.accessibility?.hint || "";
272
-
273
- accessibilityManager.readText({
274
- text: `${accessibilityTitle} ${accessibilityHint}`,
275
- });
293
+ this.handleAccessibilityFocus(item, index, dataLength);
276
294
  }
277
295
 
278
296
  return (
@@ -5,6 +5,7 @@ import { BaseFocusable } from "../BaseFocusable";
5
5
  import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
6
6
  import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
7
7
  import { withFocusableContext } from "../../Contexts/FocusableGroupContext/withFocusableContext";
8
+ import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager";
8
9
 
9
10
  type Props = {
10
11
  initialFocus?: boolean;
@@ -28,6 +29,7 @@ class Focusable extends BaseFocusable<Props> {
28
29
  isGroup: boolean;
29
30
  mouse: boolean;
30
31
  longPressTimeout = null;
32
+ accessibilityManager: AccessibilityManager;
31
33
 
32
34
  constructor(props) {
33
35
  super(props);
@@ -42,6 +44,8 @@ class Focusable extends BaseFocusable<Props> {
42
44
  this.resetLongPressTimeout = this.resetLongPressTimeout.bind(this);
43
45
  this.longPress = this.longPress.bind(this);
44
46
  this.press = this.press.bind(this);
47
+
48
+ this.accessibilityManager = AccessibilityManager.getInstance();
45
49
  }
46
50
 
47
51
  /**
@@ -128,6 +132,9 @@ class Focusable extends BaseFocusable<Props> {
128
132
  const id = this.getId();
129
133
  const focusableId = `focusable-${id}`;
130
134
 
135
+ const accessibilityProps =
136
+ this.accessibilityManager.getWebAccessibilityProps(this.props);
137
+
131
138
  return (
132
139
  <div
133
140
  id={focusableId}
@@ -140,6 +147,7 @@ class Focusable extends BaseFocusable<Props> {
140
147
  data-testid={focusableId}
141
148
  focused-teststate={focused ? "focused" : "default"}
142
149
  style={style}
150
+ {...accessibilityProps}
143
151
  >
144
152
  {children(focused, { mouse: this.mouse })}
145
153
  </div>
@@ -33,6 +33,8 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
33
33
  focusedStyles,
34
34
  pluginIdentifier,
35
35
  preferredFocus,
36
+ index,
37
+ buttonsCount,
36
38
  } = otherProps;
37
39
 
38
40
  const focusableId = getFocusableId(prefixId, suffixId);
@@ -96,8 +98,10 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
96
98
  });
97
99
 
98
100
  if (ttsLabel) {
101
+ accessibilityManager.addHeading(ttsLabel);
102
+
99
103
  accessibilityManager.readText({
100
- text: ttsLabel,
104
+ text: `button ${index + 1} of ${buttonsCount}`,
101
105
  });
102
106
  }
103
107
  };
@@ -51,6 +51,8 @@ type Props = {
51
51
  pluginIdentifier: string;
52
52
  suffixId: string;
53
53
  preferredFocus: boolean;
54
+ index: number;
55
+ buttonsCount: number;
54
56
  };
55
57
 
56
58
  export const Button = ({
@@ -60,6 +62,8 @@ export const Button = ({
60
62
  pluginIdentifier,
61
63
  suffixId,
62
64
  preferredFocus,
65
+ index,
66
+ buttonsCount,
63
67
  }: Props) => {
64
68
  if (!value(`${suffixId}_button_enabled`)) return null;
65
69
 
@@ -128,6 +132,8 @@ export const Button = ({
128
132
  },
129
133
  pluginIdentifier,
130
134
  preferredFocus,
135
+ index,
136
+ buttonsCount,
131
137
  },
132
138
  };
133
139
  };
@@ -83,6 +83,8 @@ export const TvActionButtons = ({
83
83
  pluginIdentifier: getPluginIdentifier(configuration, PREFIX, index),
84
84
  suffixId: prefixSpecificButton,
85
85
  preferredFocus: index === 0,
86
+ index,
87
+ buttonsCount,
86
88
  });
87
89
  }, buttonsCount)
88
90
  ),
@@ -2,6 +2,19 @@
2
2
 
3
3
  exports[`<TextInputTv /> renders 1`] = `
4
4
  <input
5
+ accessibilityProps={
6
+ {
7
+ "accessibilityHint": "Enter text into Search",
8
+ "accessibilityLabel": "Search",
9
+ "accessibilityRole": "text",
10
+ "accessible": true,
11
+ "aria-description": "Enter text into Search",
12
+ "aria-label": "Search",
13
+ "aria-role": "text",
14
+ "role": "text",
15
+ "tabindex": 0,
16
+ }
17
+ }
5
18
  testID="TextInput-tv"
6
19
  />
7
20
  `;
@@ -4,6 +4,7 @@ import { Appearance, Platform, StyleSheet, TextInput } from "react-native";
4
4
  import { isFunction } from "@applicaster/zapp-react-native-utils/functionUtils";
5
5
  import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
6
6
  import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
7
+ import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
7
8
 
8
9
  type Props = Partial<{
9
10
  style: any;
@@ -42,6 +43,8 @@ function TextInputTV(props: Props, ref) {
42
43
  const [colorScheme, setColorScheme] = useState(getInitialColorScheme());
43
44
  const isRTL = useIsRTL();
44
45
 
46
+ const accessibilityManager = useAccessibilityManager({});
47
+
45
48
  const onColorChange = useCallback(
46
49
  ({ colorScheme: color }) => {
47
50
  if (color !== colorScheme) {
@@ -153,6 +156,13 @@ function TextInputTV(props: Props, ref) {
153
156
  ])
154
157
  )(props);
155
158
 
159
+ const getAccessibilityProps = () => {
160
+ return {
161
+ accessibilityProps:
162
+ accessibilityManager.getInputAccessibilityProps("Search"),
163
+ };
164
+ };
165
+
156
166
  const inputProps = {
157
167
  ...getProps(),
158
168
  ...getStyle(),
@@ -161,6 +171,7 @@ function TextInputTV(props: Props, ref) {
161
171
  ...getSecureTextEntry(),
162
172
  ...getOnEndEditing(),
163
173
  ...getOnPress(),
174
+ ...getAccessibilityProps(),
164
175
  };
165
176
 
166
177
  if (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "13.0.6-rc.0",
3
+ "version": "13.0.7-alpha.2991546311",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -31,10 +31,10 @@
31
31
  "redux-mock-store": "^1.5.3"
32
32
  },
33
33
  "dependencies": {
34
- "@applicaster/applicaster-types": "13.0.6-rc.0",
35
- "@applicaster/zapp-react-native-bridge": "13.0.6-rc.0",
36
- "@applicaster/zapp-react-native-redux": "13.0.6-rc.0",
37
- "@applicaster/zapp-react-native-utils": "13.0.6-rc.0",
34
+ "@applicaster/applicaster-types": "13.0.7-alpha.2991546311",
35
+ "@applicaster/zapp-react-native-bridge": "13.0.7-alpha.2991546311",
36
+ "@applicaster/zapp-react-native-redux": "13.0.7-alpha.2991546311",
37
+ "@applicaster/zapp-react-native-utils": "13.0.7-alpha.2991546311",
38
38
  "promise": "^8.3.0",
39
39
  "react-router-native": "^5.1.2",
40
40
  "url": "^0.11.0",