@startupjs-ui/modal 0.2.0 → 0.3.1

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,25 @@
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.1](https://github.com/startupjs/startupjs-ui/compare/v0.3.0...v0.3.1) (2026-06-08)
7
+
8
+ **Note:** Version bump only for package @startupjs-ui/modal
9
+
10
+
11
+
12
+
13
+
14
+ # [0.3.0](https://github.com/startupjs/startupjs-ui/compare/v0.2.3...v0.3.0) (2026-05-27)
15
+
16
+
17
+ ### Features
18
+
19
+ * [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))
20
+
21
+
22
+
23
+
24
+
6
25
  # [0.2.0](https://github.com/startupjs/startupjs-ui/compare/v0.1.23...v0.2.0) (2026-05-04)
7
26
 
8
27
 
@@ -24,6 +24,8 @@ export interface ModalActionsProps {
24
24
  onCancel?: (event: any) => void | Promise<void>
25
25
  /** Confirm button handler */
26
26
  onConfirm?: (event: any) => void | Promise<void>
27
+ /** Test identifier */
28
+ testID?: string
27
29
  }
28
30
 
29
31
  function ModalActions ({
@@ -32,22 +34,25 @@ function ModalActions ({
32
34
  cancelLabel = DEFAULT_CANCEL_LABEL,
33
35
  confirmLabel = DEFAULT_CONFIRM_LABEL,
34
36
  onCancel,
35
- onConfirm
37
+ onConfirm,
38
+ testID
36
39
  }: ModalActionsProps): ReactNode {
37
40
  return pug`
38
- Div.root(row style=style align='right')
41
+ Div.root(row style=style testID=testID align='right')
39
42
  if children
40
43
  = children
41
44
  else
42
45
  if onCancel
43
46
  Button.action(
44
47
  color='primary'
48
+ data-part='cancel'
45
49
  onPress=onCancel
46
50
  )= cancelLabel
47
51
  if onConfirm
48
52
  Button.action(
49
53
  color='primary'
50
54
  variant='flat'
55
+ data-part='confirm'
51
56
  onPress=onConfirm
52
57
  )= confirmLabel
53
58
  `
@@ -23,6 +23,8 @@ export interface ModalHeaderProps {
23
23
  iconStyle?: StyleProp<ViewStyle>
24
24
  /** Web-only title id for dialog naming */
25
25
  titleId?: string
26
+ /** Test identifier */
27
+ testID?: string
26
28
  }
27
29
 
28
30
  function ModalHeader ({
@@ -31,10 +33,11 @@ function ModalHeader ({
31
33
  onCrossPress, // @private
32
34
  closeIcon = faTimes,
33
35
  iconStyle,
34
- titleId
36
+ titleId,
37
+ testID
35
38
  }: ModalHeaderProps): ReactNode {
36
39
  return pug`
37
- Div.root(row style=style styleName=children ? 'between' : 'right' vAlign='center')
40
+ Div.root(row style=style testID=testID styleName=children ? 'between' : 'right' vAlign='center')
38
41
  if typeof children === 'string'
39
42
  Span.title(id=titleId numberOfLines=1)= children
40
43
  else
package/index.d.ts CHANGED
@@ -42,6 +42,8 @@ export interface ModalProps {
42
42
  statusBarTranslucent?: boolean;
43
43
  /** Allowed screen orientations */
44
44
  supportedOrientations?: SupportedOrientation[];
45
+ /** Test identifier for the modal surface */
46
+ testID?: string;
45
47
  /** Callback fired after modal becomes visible */
46
48
  onShow?: () => void;
47
49
  /** Called when user clicks on the cross */
package/index.tsx CHANGED
@@ -68,6 +68,8 @@ export interface ModalProps {
68
68
  statusBarTranslucent?: boolean
69
69
  /** Allowed screen orientations */
70
70
  supportedOrientations?: SupportedOrientation[]
71
+ /** Test identifier for the modal surface */
72
+ testID?: string
71
73
  /** Callback fired after modal becomes visible */
72
74
  onShow?: () => void
73
75
  /** Called when user clicks on the cross */
@@ -107,6 +109,7 @@ function ModalRoot ({
107
109
  transparent = true,
108
110
  supportedOrientations = SUPPORTED_ORIENTATIONS,
109
111
  statusBarTranslucent,
112
+ testID,
110
113
  onChange, // DEPRECATED
111
114
  onRequestClose,
112
115
  onDismiss,
@@ -179,6 +182,7 @@ function ModalRoot ({
179
182
  variant=variant
180
183
  title=title
181
184
  role=role
185
+ testID=testID
182
186
  cancelLabel=cancelLabel
183
187
  confirmLabel=confirmLabel
184
188
  showCross=showCross
package/layout.tsx CHANGED
@@ -7,6 +7,24 @@ import ModalContent from './ModalContent'
7
7
  import ModalActions, { DEFAULT_CANCEL_LABEL, DEFAULT_CONFIRM_LABEL } from './ModalActions'
8
8
  import './index.cssx.styl'
9
9
 
10
+ function getTextFromChildren (children: ReactNode): string | undefined {
11
+ if (children == null || typeof children === 'boolean') return undefined
12
+ if (typeof children === 'string' || typeof children === 'number') {
13
+ const text = String(children).trim()
14
+ return text || undefined
15
+ }
16
+ if (Array.isArray(children)) {
17
+ const parts = children
18
+ .map(getTextFromChildren)
19
+ .filter((part): part is string => !!part)
20
+ return parts.length ? parts.join(' ').trim() : undefined
21
+ }
22
+ if (React.isValidElement(children)) {
23
+ return getTextFromChildren((children as any).props?.children)
24
+ }
25
+ return undefined
26
+ }
27
+
10
28
  export interface ModalLayoutProps {
11
29
  /** Custom styles applied to the root view */
12
30
  style?: StyleProp<ViewStyle>
@@ -20,6 +38,8 @@ export interface ModalLayoutProps {
20
38
  title?: string
21
39
  /** Accessible role for the modal surface on web @default 'dialog' */
22
40
  role?: ViewProps['role']
41
+ /** Test identifier for the modal surface */
42
+ testID?: string
23
43
  /** DEPRECATED: use cancelLabel instead */
24
44
  dismissLabel?: string
25
45
  /** Cancel action label @default 'Cancel' */
@@ -51,6 +71,7 @@ function Modal ({
51
71
  variant,
52
72
  title,
53
73
  role,
74
+ testID,
54
75
  dismissLabel,
55
76
  cancelLabel = DEFAULT_CANCEL_LABEL,
56
77
  confirmLabel = DEFAULT_CONFIRM_LABEL,
@@ -108,8 +129,8 @@ function Modal ({
108
129
  const isWindowLayout = variant === 'window'
109
130
  const hasActions = !!onCancel || !!onConfirm
110
131
  const hasHeader = !!title || !!showCross
111
- const headerTitle = !title && React.isValidElement(header) && typeof (header as any).props?.children === 'string'
112
- ? (header as any).props.children as string
132
+ const headerTitle = !title && React.isValidElement(header)
133
+ ? getTextFromChildren((header as any).props?.children)
113
134
  : undefined
114
135
  const dialogTitle = title ?? headerTitle
115
136
 
@@ -153,8 +174,12 @@ function Modal ({
153
174
  cancelLabel = 'OK'
154
175
  }
155
176
 
177
+ const headerChildren = header && React.isValidElement(header)
178
+ ? (header as any).props?.children
179
+ : undefined
180
+ const hasStringHeaderChildren = typeof headerChildren === 'string'
156
181
  const modalTitleId = useId()
157
- const titleId = dialogTitle ? modalTitleId : undefined
182
+ const titleId = dialogTitle && (title || hasStringHeaderChildren) ? modalTitleId : undefined
158
183
 
159
184
  // Handle <Modal.Header>
160
185
  const headerProps = {
@@ -209,8 +234,9 @@ function Modal ({
209
234
  style=modalStyle
210
235
  styleName=[variant]
211
236
  role=role ?? 'dialog'
237
+ testID=testID
212
238
  aria-modal
213
- aria-label=titleId ? undefined : dialogTitle
239
+ aria-label=dialogTitle
214
240
  aria-labelledby=titleId
215
241
  )
216
242
  = header
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startupjs-ui/modal",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -8,18 +8,18 @@
8
8
  "types": "index.d.ts",
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "@startupjs-ui/button": "^0.2.0",
12
- "@startupjs-ui/core": "^0.2.0",
13
- "@startupjs-ui/div": "^0.2.0",
14
- "@startupjs-ui/icon": "^0.2.0",
15
- "@startupjs-ui/portal": "^0.2.0",
16
- "@startupjs-ui/scroll-view": "^0.2.0",
17
- "@startupjs-ui/span": "^0.2.0"
11
+ "@startupjs-ui/button": "^0.3.1",
12
+ "@startupjs-ui/core": "^0.3.0",
13
+ "@startupjs-ui/div": "^0.3.1",
14
+ "@startupjs-ui/icon": "^0.3.0",
15
+ "@startupjs-ui/portal": "^0.3.0",
16
+ "@startupjs-ui/scroll-view": "^0.3.0",
17
+ "@startupjs-ui/span": "^0.3.1"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "react": "*",
21
21
  "react-native": "*",
22
22
  "startupjs": "*"
23
23
  },
24
- "gitHead": "0c586b841cba1c9d820542f6eca07470f5ea2659"
24
+ "gitHead": "60311773bdc83f354c797a272774304502d28c58"
25
25
  }