@startupjs-ui/modal 0.1.22 → 0.2.0-alpha.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 +22 -0
- package/ModalHeader/index.cssx.styl +11 -0
- package/ModalHeader/index.tsx +6 -2
- package/README.mdx +1 -0
- package/index.d.ts +3 -1
- package/index.tsx +5 -1
- package/layout.tsx +22 -4
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
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.2.0-alpha.1](https://github.com/startupjs/startupjs-ui/compare/v0.2.0-alpha.0...v0.2.0-alpha.1) (2026-04-10)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **dialogs:** use 'alertdialog' role for confirm(), prompt(), alert() ([ae2989f](https://github.com/startupjs/startupjs-ui/commit/ae2989fd6cf7b19a189330b3a180226727efc3fe))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [0.2.0-alpha.0](https://github.com/startupjs/startupjs-ui/compare/v0.1.22...v0.2.0-alpha.0) (2026-03-27)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* fix and improve accessibility of various components. Add storybook with tests. ([#21](https://github.com/startupjs/startupjs-ui/issues/21)) ([83b6576](https://github.com/startupjs/startupjs-ui/commit/83b65767ed61b24209f71b143ba1c2986170ab58))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
## [0.1.22](https://github.com/startupjs/startupjs-ui/compare/v0.1.21...v0.1.22) (2026-03-25)
|
|
7
29
|
|
|
8
30
|
**Note:** Version bump only for package @startupjs-ui/modal
|
package/ModalHeader/index.tsx
CHANGED
|
@@ -21,6 +21,8 @@ export interface ModalHeaderProps {
|
|
|
21
21
|
closeIcon?: object
|
|
22
22
|
/** Style applied to the close icon */
|
|
23
23
|
iconStyle?: StyleProp<ViewStyle>
|
|
24
|
+
/** Web-only title id for dialog naming */
|
|
25
|
+
titleId?: string
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
function ModalHeader ({
|
|
@@ -28,16 +30,18 @@ function ModalHeader ({
|
|
|
28
30
|
children,
|
|
29
31
|
onCrossPress, // @private
|
|
30
32
|
closeIcon = faTimes,
|
|
31
|
-
iconStyle
|
|
33
|
+
iconStyle,
|
|
34
|
+
titleId
|
|
32
35
|
}: ModalHeaderProps): ReactNode {
|
|
33
36
|
return pug`
|
|
34
37
|
Div.root(row style=style styleName=children ? 'between' : 'right' vAlign='center')
|
|
35
38
|
if typeof children === 'string'
|
|
36
|
-
Span.title(numberOfLines=1)= children
|
|
39
|
+
Span.title(id=titleId numberOfLines=1)= children
|
|
37
40
|
else
|
|
38
41
|
= children
|
|
39
42
|
if onCrossPress
|
|
40
43
|
Div.close(onPress=onCrossPress)
|
|
44
|
+
Span.srOnly Close dialog
|
|
41
45
|
Icon.icon(
|
|
42
46
|
style=iconStyle
|
|
43
47
|
icon=closeIcon
|
package/README.mdx
CHANGED
|
@@ -160,6 +160,7 @@ The modal can automatically display action buttons at the bottom:
|
|
|
160
160
|
| `$visible` | `any` | | Scoped model for two-way visibility binding |
|
|
161
161
|
| `ref` | `RefObject` | | Imperative ref exposing `open()` and `close()` |
|
|
162
162
|
| `title` | `string` | | Header title text |
|
|
163
|
+
| `role` | `string` | `'dialog'` | Accessible role for the modal surface on web |
|
|
163
164
|
| `cancelLabel` | `string` | `'Cancel'` | Label for the cancel button |
|
|
164
165
|
| `confirmLabel` | `string` | `'Confirm'` | Label for the confirm button |
|
|
165
166
|
| `showCross` | `boolean` | `true` | Whether to show a close icon in the header |
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// DO NOT MODIFY THIS FILE - IT IS AUTOMATICALLY GENERATED ON COMMITS.
|
|
3
3
|
|
|
4
4
|
import { type ReactNode, type ComponentType, type RefObject } from 'react';
|
|
5
|
-
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
5
|
+
import { type StyleProp, type ViewStyle, type ViewProps } from 'react-native';
|
|
6
6
|
type SupportedOrientation = 'portrait' | 'portrait-upside-down' | 'landscape' | 'landscape-left' | 'landscape-right';
|
|
7
7
|
export declare const _PropsJsonSchema: {};
|
|
8
8
|
export interface ModalProps {
|
|
@@ -22,6 +22,8 @@ export interface ModalProps {
|
|
|
22
22
|
ref?: RefObject<any>;
|
|
23
23
|
/** Header title text */
|
|
24
24
|
title?: string;
|
|
25
|
+
/** Accessible role for the modal surface on web @default 'dialog' */
|
|
26
|
+
role?: ViewProps['role'];
|
|
25
27
|
/** Label for cancel action @default 'Cancel' */
|
|
26
28
|
cancelLabel?: string;
|
|
27
29
|
/** Label for confirm action @default 'Confirm' */
|
package/index.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import React, {
|
|
|
5
5
|
type ComponentType,
|
|
6
6
|
type RefObject
|
|
7
7
|
} from 'react'
|
|
8
|
-
import { SafeAreaView, Modal as RNModal, type StyleProp, type ViewStyle } from 'react-native'
|
|
8
|
+
import { SafeAreaView, Modal as RNModal, type StyleProp, type ViewStyle, type ViewProps } from 'react-native'
|
|
9
9
|
import { pug, observer, $ } from 'startupjs'
|
|
10
10
|
import { themed } from '@startupjs-ui/core'
|
|
11
11
|
import Portal from '@startupjs-ui/portal'
|
|
@@ -48,6 +48,8 @@ export interface ModalProps {
|
|
|
48
48
|
ref?: RefObject<any>
|
|
49
49
|
/** Header title text */
|
|
50
50
|
title?: string
|
|
51
|
+
/** Accessible role for the modal surface on web @default 'dialog' */
|
|
52
|
+
role?: ViewProps['role']
|
|
51
53
|
/** Label for cancel action @default 'Cancel' */
|
|
52
54
|
cancelLabel?: string
|
|
53
55
|
/** Label for confirm action @default 'Confirm' */
|
|
@@ -95,6 +97,7 @@ function ModalRoot ({
|
|
|
95
97
|
$visible,
|
|
96
98
|
ref,
|
|
97
99
|
title,
|
|
100
|
+
role,
|
|
98
101
|
cancelLabel = DEFAULT_CANCEL_LABEL,
|
|
99
102
|
confirmLabel = DEFAULT_CONFIRM_LABEL,
|
|
100
103
|
showCross = true,
|
|
@@ -175,6 +178,7 @@ function ModalRoot ({
|
|
|
175
178
|
modalStyle=modalStyle
|
|
176
179
|
variant=variant
|
|
177
180
|
title=title
|
|
181
|
+
role=role
|
|
178
182
|
cancelLabel=cancelLabel
|
|
179
183
|
confirmLabel=confirmLabel
|
|
180
184
|
showCross=showCross
|
package/layout.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, { type ReactNode, type ComponentType } from 'react'
|
|
2
|
-
import { View, TouchableOpacity, type StyleProp, type ViewStyle } from 'react-native'
|
|
1
|
+
import React, { useId, type ReactNode, type ComponentType } from 'react'
|
|
2
|
+
import { View, TouchableOpacity, type StyleProp, type ViewStyle, type ViewProps } from 'react-native'
|
|
3
3
|
import { pug, observer } from 'startupjs'
|
|
4
4
|
import { themed } from '@startupjs-ui/core'
|
|
5
5
|
import ModalHeader from './ModalHeader'
|
|
@@ -18,6 +18,8 @@ export interface ModalLayoutProps {
|
|
|
18
18
|
variant?: 'window' | 'fullscreen'
|
|
19
19
|
/** Title rendered when no custom header provided */
|
|
20
20
|
title?: string
|
|
21
|
+
/** Accessible role for the modal surface on web @default 'dialog' */
|
|
22
|
+
role?: ViewProps['role']
|
|
21
23
|
/** DEPRECATED: use cancelLabel instead */
|
|
22
24
|
dismissLabel?: string
|
|
23
25
|
/** Cancel action label @default 'Cancel' */
|
|
@@ -48,6 +50,7 @@ function Modal ({
|
|
|
48
50
|
children,
|
|
49
51
|
variant,
|
|
50
52
|
title,
|
|
53
|
+
role,
|
|
51
54
|
dismissLabel,
|
|
52
55
|
cancelLabel = DEFAULT_CANCEL_LABEL,
|
|
53
56
|
confirmLabel = DEFAULT_CONFIRM_LABEL,
|
|
@@ -105,6 +108,10 @@ function Modal ({
|
|
|
105
108
|
const isWindowLayout = variant === 'window'
|
|
106
109
|
const hasActions = !!onCancel || !!onConfirm
|
|
107
110
|
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
|
|
113
|
+
: undefined
|
|
114
|
+
const dialogTitle = title ?? headerTitle
|
|
108
115
|
|
|
109
116
|
const _onCrossPress = async (event: any) => {
|
|
110
117
|
event.persist() // TODO: remove in react 17
|
|
@@ -146,9 +153,13 @@ function Modal ({
|
|
|
146
153
|
cancelLabel = 'OK'
|
|
147
154
|
}
|
|
148
155
|
|
|
156
|
+
const modalTitleId = useId()
|
|
157
|
+
const titleId = dialogTitle ? modalTitleId : undefined
|
|
158
|
+
|
|
149
159
|
// Handle <Modal.Header>
|
|
150
160
|
const headerProps = {
|
|
151
|
-
onCrossPress: showCross ? _onCrossPress : undefined
|
|
161
|
+
onCrossPress: showCross ? _onCrossPress : undefined,
|
|
162
|
+
titleId
|
|
152
163
|
}
|
|
153
164
|
|
|
154
165
|
header = header
|
|
@@ -185,7 +196,10 @@ function Modal ({
|
|
|
185
196
|
: React.createElement(ModalContent, contentProps, contentChildren)
|
|
186
197
|
|
|
187
198
|
return pug`
|
|
188
|
-
View.root(
|
|
199
|
+
View.root(
|
|
200
|
+
style=style
|
|
201
|
+
styleName=[variant]
|
|
202
|
+
)
|
|
189
203
|
if isWindowLayout
|
|
190
204
|
TouchableOpacity.overlay(
|
|
191
205
|
activeOpacity=1
|
|
@@ -194,6 +208,10 @@ function Modal ({
|
|
|
194
208
|
ModalElement.modal(
|
|
195
209
|
style=modalStyle
|
|
196
210
|
styleName=[variant]
|
|
211
|
+
role=role ?? 'dialog'
|
|
212
|
+
aria-modal
|
|
213
|
+
aria-label=titleId ? undefined : dialogTitle
|
|
214
|
+
aria-labelledby=titleId
|
|
197
215
|
)
|
|
198
216
|
= header
|
|
199
217
|
= content
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@startupjs-ui/modal",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.0-alpha.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.1
|
|
12
|
-
"@startupjs-ui/core": "^0.1
|
|
13
|
-
"@startupjs-ui/div": "^0.1
|
|
14
|
-
"@startupjs-ui/icon": "^0.1
|
|
15
|
-
"@startupjs-ui/portal": "^0.1
|
|
16
|
-
"@startupjs-ui/scroll-view": "^0.1
|
|
17
|
-
"@startupjs-ui/span": "^0.1
|
|
11
|
+
"@startupjs-ui/button": "^0.2.0-alpha.1",
|
|
12
|
+
"@startupjs-ui/core": "^0.2.0-alpha.1",
|
|
13
|
+
"@startupjs-ui/div": "^0.2.0-alpha.1",
|
|
14
|
+
"@startupjs-ui/icon": "^0.2.0-alpha.1",
|
|
15
|
+
"@startupjs-ui/portal": "^0.2.0-alpha.1",
|
|
16
|
+
"@startupjs-ui/scroll-view": "^0.2.0-alpha.1",
|
|
17
|
+
"@startupjs-ui/span": "^0.2.0-alpha.1"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"react": "*",
|
|
21
21
|
"react-native": "*",
|
|
22
22
|
"startupjs": "*"
|
|
23
23
|
},
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "b48004779559b16c96a2a1995dab13b998eafce9"
|
|
25
25
|
}
|