@startupjs-ui/input 0.2.3 → 0.3.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [0.3.0](https://github.com/startupjs/startupjs-ui/compare/v0.2.3...v0.3.0) (2026-05-27)
7
+
8
+
9
+ ### Features
10
+
11
+ * [BREAKING] [0.3] improve accessibility props for E2E tests. Support testID everywhere ([#31](https://github.com/startupjs/startupjs-ui/issues/31)) ([882588c](https://github.com/startupjs/startupjs-ui/commit/882588ca37d5e1fd14b5717b5697cf9ed47042e4))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [0.2.3](https://github.com/startupjs/startupjs-ui/compare/v0.2.2...v0.2.3) (2026-05-15)
7
18
 
8
19
  **Note:** Version bump only for package @startupjs-ui/input
package/README.mdx CHANGED
@@ -32,7 +32,7 @@ Layout behavior follows these rules:
32
32
 
33
33
  **Additional props**
34
34
 
35
- The component supports `disabled` to prevent interaction, `readonly` for a non-editable display, `required` to mark the field as required, and `placeholder` for placeholder text. For select-like inputs, use `options` or `enum`; for array inputs, use `items`; and for object inputs, use `properties`. The `configuration` prop allows overriding the wrapper configuration. Use `testId` for testing and `ref` for imperative access to the underlying input.
35
+ The component supports `disabled` to prevent interaction, `readonly` for a non-editable display, `required` to mark the field as required, and `placeholder` for placeholder text. For select-like inputs, use `options` or `enum`; for array inputs, use `items`; and for object inputs, use `properties`. The `configuration` prop allows overriding the wrapper configuration. Use `testID` for testing and `ref` for imperative access to the underlying input.
36
36
 
37
37
  Change handlers vary by input type: `onChange` (checkbox, select, range, etc.), `onChangeText` (text), `onChangeNumber` (number), `onChangeDate` (date/time), and `onChangeColor` (color). Focus and blur events are available via `onFocus` and `onBlur`.
38
38
 
@@ -1,10 +1,10 @@
1
1
  export default function getInputTestId (props: {
2
- testId?: string
2
+ testID?: string
3
3
  label?: unknown
4
4
  description?: unknown
5
5
  placeholder?: unknown
6
6
  } & Record<string, any>): string | undefined {
7
- if (props.testId) return props.testId
7
+ if (props.testID) return props.testID
8
8
 
9
9
  const inputName =
10
10
  (typeof props.label === 'string' && props.label !== '' ? props.label : null) ??
package/index.d.ts CHANGED
@@ -29,8 +29,8 @@ export interface InputProps {
29
29
  disabled?: boolean;
30
30
  /** Render as read-only */
31
31
  readonly?: boolean;
32
- /** Test id for generated testID */
33
- testId?: string;
32
+ /** Test identifier */
33
+ testID?: string;
34
34
  /** Placeholder text */
35
35
  placeholder?: string;
36
36
  /** Options for select-like inputs */
package/index.tsx CHANGED
@@ -32,8 +32,8 @@ export interface InputProps {
32
32
  disabled?: boolean
33
33
  /** Render as read-only */
34
34
  readonly?: boolean
35
- /** Test id for generated testID */
36
- testId?: string
35
+ /** Test identifier */
36
+ testID?: string
37
37
  /** Placeholder text */
38
38
  placeholder?: string
39
39
  /** Options for select-like inputs */
package/inputs.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { type ReactNode, type RefObject } from 'react'
2
2
  import { type StyleProp, type ViewStyle } from 'react-native'
3
3
  import { pug, useBind } from 'startupjs'
4
+ import { type UIRole } from '@startupjs-ui/core'
4
5
  import ArrayInput from '@startupjs-ui/array-input'
5
6
  import Card from '@startupjs-ui/card'
6
7
  import Checkbox from '@startupjs-ui/checkbox'
@@ -20,6 +21,21 @@ import wrapInput, { isWrapped } from './wrapInput'
20
21
  import useCustomInputs from './useCustomInputs'
21
22
  import { customInputs } from './globalCustomInputs'
22
23
 
24
+ type CardWrapperProps = {
25
+ style?: StyleProp<ViewStyle>
26
+ testID?: string
27
+ id?: string
28
+ role?: UIRole
29
+ 'aria-label'?: string
30
+ 'aria-labelledby'?: string
31
+ 'aria-describedby'?: string
32
+ 'aria-errormessage'?: string
33
+ 'aria-invalid'?: boolean
34
+ 'aria-required'?: boolean
35
+ 'aria-disabled'?: boolean
36
+ 'aria-readonly'?: boolean
37
+ }
38
+
23
39
  export type InputUseProps = (
24
40
  props: Record<string, any>,
25
41
  ref?: RefObject<any>
@@ -85,7 +101,10 @@ const useDateProps = ({
85
101
  return {
86
102
  mode: 'date',
87
103
  date: value,
88
- configuration: getLabelableConfiguration(props),
104
+ configuration: {
105
+ isLabelClickable: !props.disabled && !props.readonly,
106
+ _webLabelMode: 'aria' as const
107
+ },
89
108
  onChangeDate,
90
109
  _onLabelPress: () => ref?.current?.focus(),
91
110
  ...props
@@ -103,7 +122,10 @@ const useDateTimeProps = ({
103
122
  return {
104
123
  mode: 'datetime',
105
124
  date: value,
106
- configuration: getLabelableConfiguration(props),
125
+ configuration: {
126
+ isLabelClickable: !props.disabled && !props.readonly,
127
+ _webLabelMode: 'aria' as const
128
+ },
107
129
  onChangeDate,
108
130
  _onLabelPress: () => ref?.current?.focus(),
109
131
  ...props
@@ -121,7 +143,10 @@ const useTimeProps = ({
121
143
  return {
122
144
  mode: 'time',
123
145
  date: value,
124
- configuration: getLabelableConfiguration(props),
146
+ configuration: {
147
+ isLabelClickable: !props.disabled && !props.readonly,
148
+ _webLabelMode: 'aria' as const
149
+ },
125
150
  onChangeDate,
126
151
  _onLabelPress: () => ref?.current?.focus(),
127
152
  ...props
@@ -259,10 +284,34 @@ const useTextProps = ({
259
284
  }
260
285
  }
261
286
 
262
- function cardWrapper (style: StyleProp<ViewStyle> | undefined, children: ReactNode): ReactNode {
287
+ function cardWrapper ({
288
+ style,
289
+ testID,
290
+ id,
291
+ role,
292
+ 'aria-label': ariaLabel,
293
+ 'aria-labelledby': ariaLabelledBy,
294
+ 'aria-describedby': ariaDescribedBy,
295
+ 'aria-errormessage': ariaErrorMessage,
296
+ 'aria-invalid': ariaInvalid,
297
+ 'aria-required': ariaRequired,
298
+ 'aria-disabled': ariaDisabled,
299
+ 'aria-readonly': ariaReadonly
300
+ }: CardWrapperProps, children: ReactNode): ReactNode {
263
301
  return pug`
264
302
  Card(
265
303
  style=style
304
+ testID=testID
305
+ id=id
306
+ role=role
307
+ aria-label=ariaLabel
308
+ aria-labelledby=ariaLabelledBy
309
+ aria-describedby=ariaDescribedBy
310
+ aria-errormessage=ariaErrorMessage
311
+ aria-invalid=ariaInvalid
312
+ aria-required=ariaRequired
313
+ aria-disabled=ariaDisabled
314
+ aria-readonly=ariaReadonly
266
315
  variant='outlined'
267
316
  )
268
317
  = children
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startupjs-ui/input",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -13,25 +13,25 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@fortawesome/free-solid-svg-icons": "^7.1.0",
16
- "@startupjs-ui/array-input": "^0.2.3",
17
- "@startupjs-ui/card": "^0.2.0",
18
- "@startupjs-ui/checkbox": "^0.2.0",
19
- "@startupjs-ui/color-picker": "^0.2.0",
20
- "@startupjs-ui/core": "^0.2.0",
21
- "@startupjs-ui/date-time-picker": "^0.2.0",
22
- "@startupjs-ui/div": "^0.2.0",
23
- "@startupjs-ui/file-input": "^0.2.2",
24
- "@startupjs-ui/icon": "^0.2.0",
25
- "@startupjs-ui/multi-select": "^0.2.0",
26
- "@startupjs-ui/number-input": "^0.2.0",
27
- "@startupjs-ui/object-input": "^0.2.3",
28
- "@startupjs-ui/password-input": "^0.2.0",
29
- "@startupjs-ui/radio": "^0.2.0",
30
- "@startupjs-ui/range-input": "^0.2.3",
31
- "@startupjs-ui/rank": "^0.2.0",
32
- "@startupjs-ui/select": "^0.2.0",
33
- "@startupjs-ui/span": "^0.2.0",
34
- "@startupjs-ui/text-input": "^0.2.0",
16
+ "@startupjs-ui/array-input": "^0.3.0",
17
+ "@startupjs-ui/card": "^0.3.0",
18
+ "@startupjs-ui/checkbox": "^0.3.0",
19
+ "@startupjs-ui/color-picker": "^0.3.0",
20
+ "@startupjs-ui/core": "^0.3.0",
21
+ "@startupjs-ui/date-time-picker": "^0.3.0",
22
+ "@startupjs-ui/div": "^0.3.0",
23
+ "@startupjs-ui/file-input": "^0.3.0",
24
+ "@startupjs-ui/icon": "^0.3.0",
25
+ "@startupjs-ui/multi-select": "^0.3.0",
26
+ "@startupjs-ui/number-input": "^0.3.0",
27
+ "@startupjs-ui/object-input": "^0.3.0",
28
+ "@startupjs-ui/password-input": "^0.3.0",
29
+ "@startupjs-ui/radio": "^0.3.0",
30
+ "@startupjs-ui/range-input": "^0.3.0",
31
+ "@startupjs-ui/rank": "^0.3.0",
32
+ "@startupjs-ui/select": "^0.3.0",
33
+ "@startupjs-ui/span": "^0.3.0",
34
+ "@startupjs-ui/text-input": "^0.3.0",
35
35
  "lodash": "^4.17.20"
36
36
  },
37
37
  "peerDependencies": {
@@ -39,5 +39,5 @@
39
39
  "react-native": "*",
40
40
  "startupjs": "*"
41
41
  },
42
- "gitHead": "6e854934a9a9d2484291670dd5955ba8ad9af621"
42
+ "gitHead": "8d212b47680af1dfe582f9759b38724b46488e25"
43
43
  }
package/wrapInput.tsx CHANGED
@@ -117,8 +117,7 @@ export default function wrapInput (Component: any, configuration: InputWrapperCo
117
117
  const generatedTestID = props.testID ?? getInputTestId({
118
118
  ...props,
119
119
  label,
120
- description,
121
- testId: props.testID
120
+ description
122
121
  })
123
122
  const semanticBaseId = typeof generatedTestID === 'string' && generatedTestID !== ''
124
123
  ? generatedTestID
@@ -139,7 +138,7 @@ export default function wrapInput (Component: any, configuration: InputWrapperCo
139
138
  ]
140
139
  const requiredAsterisk = required === true
141
140
  ? pug`
142
- Text.required(aria-hidden=IS_WEB ? true : undefined)= ' *'
141
+ Text.required(aria-hidden)= ' *'
143
142
  `
144
143
  : null
145
144
  const WebLabelElement = 'label'
@@ -190,13 +189,11 @@ export default function wrapInput (Component: any, configuration: InputWrapperCo
190
189
  const describedBy = [descriptionId].filter(Boolean).join(' ') || undefined
191
190
 
192
191
  if (props['aria-label'] == null) {
193
- if (props.accessibilityLabel != null) inputAccessibilityProps['aria-label'] = props.accessibilityLabel
194
- else if (label) inputAccessibilityProps['aria-label'] = label
192
+ if (label) inputAccessibilityProps['aria-label'] = label
195
193
  }
196
194
 
197
195
  if (inputId) {
198
196
  inputAccessibilityProps.id = inputId
199
- inputAccessibilityProps.nativeID = inputId
200
197
  }
201
198
  if (required === true) inputAccessibilityProps['aria-required'] = true
202
199
  if (labelId) inputAccessibilityProps['aria-labelledby'] = labelId