@startupjs-ui/modal 0.1.19 → 0.2.0-alpha.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,33 @@
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.0](https://github.com/startupjs/startupjs-ui/compare/v0.1.22...v0.2.0-alpha.0) (2026-03-27)
7
+
8
+
9
+ ### Features
10
+
11
+ * 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))
12
+
13
+
14
+
15
+
16
+
17
+ ## [0.1.22](https://github.com/startupjs/startupjs-ui/compare/v0.1.21...v0.1.22) (2026-03-25)
18
+
19
+ **Note:** Version bump only for package @startupjs-ui/modal
20
+
21
+
22
+
23
+
24
+
25
+ ## [0.1.21](https://github.com/startupjs/startupjs-ui/compare/v0.1.20...v0.1.21) (2026-03-25)
26
+
27
+ **Note:** Version bump only for package @startupjs-ui/modal
28
+
29
+
30
+
31
+
32
+
6
33
  ## [0.1.19](https://github.com/startupjs/startupjs-ui/compare/v0.1.18...v0.1.19) (2026-03-17)
7
34
 
8
35
  **Note:** Version bump only for package @startupjs-ui/modal
@@ -18,3 +18,14 @@ $gutter = $UI.gutters.m
18
18
 
19
19
  .icon
20
20
  color: var(--color-text-description)
21
+
22
+ .srOnly
23
+ position absolute
24
+ width 1px
25
+ height 1px
26
+ padding 0
27
+ margin -1px
28
+ overflow hidden
29
+ clip rect(0, 0, 0, 0)
30
+ white-space nowrap
31
+ border 0
@@ -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/layout.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { type ReactNode, type ComponentType } from 'react'
1
+ import React, { useId, type ReactNode, type ComponentType } from 'react'
2
2
  import { View, TouchableOpacity, type StyleProp, type ViewStyle } from 'react-native'
3
3
  import { pug, observer } from 'startupjs'
4
4
  import { themed } from '@startupjs-ui/core'
@@ -105,6 +105,10 @@ function Modal ({
105
105
  const isWindowLayout = variant === 'window'
106
106
  const hasActions = !!onCancel || !!onConfirm
107
107
  const hasHeader = !!title || !!showCross
108
+ const headerTitle = !title && React.isValidElement(header) && typeof (header as any).props?.children === 'string'
109
+ ? (header as any).props.children as string
110
+ : undefined
111
+ const dialogTitle = title ?? headerTitle
108
112
 
109
113
  const _onCrossPress = async (event: any) => {
110
114
  event.persist() // TODO: remove in react 17
@@ -146,9 +150,13 @@ function Modal ({
146
150
  cancelLabel = 'OK'
147
151
  }
148
152
 
153
+ const modalTitleId = useId()
154
+ const titleId = dialogTitle ? modalTitleId : undefined
155
+
149
156
  // Handle <Modal.Header>
150
157
  const headerProps = {
151
- onCrossPress: showCross ? _onCrossPress : undefined
158
+ onCrossPress: showCross ? _onCrossPress : undefined,
159
+ titleId
152
160
  }
153
161
 
154
162
  header = header
@@ -185,7 +193,10 @@ function Modal ({
185
193
  : React.createElement(ModalContent, contentProps, contentChildren)
186
194
 
187
195
  return pug`
188
- View.root(style=style styleName=[variant])
196
+ View.root(
197
+ style=style
198
+ styleName=[variant]
199
+ )
189
200
  if isWindowLayout
190
201
  TouchableOpacity.overlay(
191
202
  activeOpacity=1
@@ -194,6 +205,10 @@ function Modal ({
194
205
  ModalElement.modal(
195
206
  style=modalStyle
196
207
  styleName=[variant]
208
+ role='dialog'
209
+ aria-modal=true
210
+ aria-label=titleId ? undefined : dialogTitle
211
+ aria-labelledby=titleId
197
212
  )
198
213
  = header
199
214
  = content
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startupjs-ui/modal",
3
- "version": "0.1.19",
3
+ "version": "0.2.0-alpha.0",
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.19",
12
- "@startupjs-ui/core": "^0.1.19",
13
- "@startupjs-ui/div": "^0.1.19",
14
- "@startupjs-ui/icon": "^0.1.19",
15
- "@startupjs-ui/portal": "^0.1.19",
16
- "@startupjs-ui/scroll-view": "^0.1.19",
17
- "@startupjs-ui/span": "^0.1.19"
11
+ "@startupjs-ui/button": "^0.2.0-alpha.0",
12
+ "@startupjs-ui/core": "^0.2.0-alpha.0",
13
+ "@startupjs-ui/div": "^0.2.0-alpha.0",
14
+ "@startupjs-ui/icon": "^0.2.0-alpha.0",
15
+ "@startupjs-ui/portal": "^0.2.0-alpha.0",
16
+ "@startupjs-ui/scroll-view": "^0.2.0-alpha.0",
17
+ "@startupjs-ui/span": "^0.2.0-alpha.0"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "react": "*",
21
21
  "react-native": "*",
22
22
  "startupjs": "*"
23
23
  },
24
- "gitHead": "bfcca786dc363f42a09b6eef4feb7ca8139302fc"
24
+ "gitHead": "a428246a18d0e7f77809043c8240253240d11d66"
25
25
  }