@instructure/ui-modal 8.23.1-snapshot.7 → 8.24.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.
@@ -30,6 +30,9 @@ import {
30
30
  Children as ChildrenPropTypes
31
31
  } from '@instructure/ui-prop-types'
32
32
  import { transitionTypePropType } from '@instructure/ui-motion'
33
+
34
+ import { Dialog } from '@instructure/ui-dialog'
35
+
33
36
  import { ModalHeader } from './ModalHeader'
34
37
  import { ModalBody } from './ModalBody'
35
38
  import { ModalFooter } from './ModalFooter'
@@ -39,177 +42,201 @@ import type {
39
42
  PropValidators,
40
43
  ModalTheme,
41
44
  OtherHTMLAttributes,
42
- LiveRegion
45
+ LiveRegion,
46
+ UIElement
43
47
  } from '@instructure/shared-types'
44
48
  import type { PortalNode } from '@instructure/ui-portal'
45
49
  import type { PositionMountNode } from '@instructure/ui-position'
46
50
  import type { TransitionType } from '@instructure/ui-motion'
47
51
  import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
48
52
 
49
- type ModalOwnProps = {
50
- label: string
51
- children: React.ReactNode // TODO: enforceOrder([ModalHeader, ModalBody, ModalFooter], [ModalHeader, ModalBody], [ModalBody, ModalFooter], [ModalBody])
52
- as?: AsElementType
53
- size?: 'auto' | 'small' | 'medium' | 'large' | 'fullscreen'
54
- variant?: 'default' | 'inverse'
53
+ type ModalPropsForPortal = {
54
+ /**
55
+ * Whether or not the `<Modal />` is open
56
+ */
55
57
  open?: boolean
56
- defaultFocusElement?: React.ReactElement | ((...args: any[]) => any)
57
- shouldReturnFocus?: boolean
58
- shouldCloseOnDocumentClick?: boolean
59
- onOpen?: (DOMNode: PortalNode) => void
60
- onClose?: (...args: any[]) => any
61
- onDismiss?: (...args: any[]) => any
62
- contentRef?: (...args: any[]) => any
58
+
59
+ /**
60
+ * An element or a function returning an element to use as the mount node
61
+ * for the `<Modal />` (defaults to `document.body`)
62
+ */
63
63
  mountNode?: PositionMountNode
64
+
65
+ /**
66
+ * Insert the element at the 'top' of the mountNode or at the 'bottom'
67
+ */
64
68
  insertAt?: 'bottom' | 'top'
65
- liveRegion?: LiveRegion
66
- transition?: TransitionType
67
- onEnter?: (...args: any[]) => any
68
- onEntering?: (...args: any[]) => any
69
- onEntered?: (...args: any[]) => any
70
- onExit?: (...args: any[]) => any
71
- onExiting?: (...args: any[]) => any
72
- onExited?: (type?: TransitionType) => void
73
- constrain?: 'window' | 'parent'
74
- overflow?: 'scroll' | 'fit'
75
- }
76
69
 
77
- type PropKeys = keyof ModalOwnProps
70
+ /**
71
+ * Callback fired when `<Modal />` content has been mounted in the DOM
72
+ */
73
+ onOpen?: (DOMNode: PortalNode) => void
78
74
 
79
- type AllowedPropKeys = Readonly<Array<PropKeys>>
75
+ /**
76
+ * Callback fired when `<Modal />` has been unmounted from the DOM
77
+ */
78
+ onClose?: () => void
79
+ }
80
80
 
81
- type ModalProps = ModalOwnProps &
82
- WithStyleProps<ModalTheme, ModalStyle> &
83
- OtherHTMLAttributes<ModalOwnProps>
81
+ type ModalPropsForTransition = {
82
+ transition?: TransitionType
84
83
 
85
- type ModalStyle = ComponentStyle<'modal' | 'constrainContext'>
84
+ /**
85
+ * Callback fired before the <Modal /> transitions in
86
+ */
87
+ onEnter?: () => void
86
88
 
87
- const propTypes: PropValidators<PropKeys> = {
88
89
  /**
89
- * An accessible label for the `<Modal />` content
90
+ * Callback fired as the <Modal /> begins to transition in
90
91
  */
91
- label: PropTypes.string.isRequired,
92
+ onEntering?: () => void
92
93
 
93
94
  /**
94
- * The children to be rendered within the `<Modal />`
95
+ * Callback fired after the <Modal /> finishes transitioning in
95
96
  */
96
- children: ChildrenPropTypes.enforceOrder(
97
- [ModalHeader, ModalBody, ModalFooter],
98
- [ModalHeader, ModalBody],
99
- [ModalBody, ModalFooter],
100
- [ModalBody]
101
- ),
97
+ onEntered?: (type?: TransitionType) => void
102
98
 
103
99
  /**
104
- * The element to render the dialog as, `span` by default
100
+ * Callback fired right before the <Modal /> transitions out
105
101
  */
106
- as: PropTypes.elementType,
102
+ onExit?: () => void
107
103
 
108
104
  /**
109
- * The size of the `<Modal />` content
105
+ * Callback fired as the <Modal /> begins to transition out
110
106
  */
111
- size: PropTypes.oneOf(['auto', 'small', 'medium', 'large', 'fullscreen']),
107
+ onExiting?: () => void
112
108
 
113
109
  /**
114
- * Designates the background style of the `<Modal />`
110
+ * Callback fired after the <Modal /> finishes transitioning out
115
111
  */
116
- variant: PropTypes.oneOf(['default', 'inverse']),
112
+ onExited?: (type?: TransitionType) => void
113
+ }
117
114
 
115
+ type ModalPropsForDialog = {
118
116
  /**
119
- * Whether or not the `<Modal />` is open
117
+ * An accessible label for the `<Modal />` content
120
118
  */
121
- open: PropTypes.bool,
119
+ label: string
122
120
 
123
121
  /**
124
- * An element or a function returning an element to focus by default
122
+ * The element to render the dialog as, `span` by default
125
123
  */
126
- defaultFocusElement: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
124
+ as?: AsElementType
127
125
 
128
126
  /**
129
127
  * Whether focus should be returned to the trigger when the `<Modal/>` is closed
130
128
  */
131
- shouldReturnFocus: PropTypes.bool,
129
+ shouldReturnFocus?: boolean
132
130
 
133
131
  /**
134
132
  * Whether the `<Modal/>` should request close when the document is clicked
135
133
  */
136
- shouldCloseOnDocumentClick: PropTypes.bool,
134
+ shouldCloseOnDocumentClick?: boolean
137
135
 
138
136
  /**
139
- * Callback fired when `<Modal />` content has been mounted in the DOM
137
+ * Callback fired when the `<Modal />` is requesting to be closed
140
138
  */
141
- onOpen: PropTypes.func,
139
+ onDismiss?: (
140
+ event: React.UIEvent | React.FocusEvent,
141
+ documentClick?: boolean
142
+ ) => void
142
143
 
143
144
  /**
144
- * Callback fired when `<Modal />` has been unmounted from the DOM
145
+ * An element, function returning an element, or array of elements that will not be hidden from
146
+ * the screen reader when the `<Modal />` is open
145
147
  */
146
- onClose: PropTypes.func,
148
+ liveRegion?: LiveRegion
147
149
 
148
150
  /**
149
- * Callback fired when the `<Modal />` is requesting to be closed
151
+ * An element or a function returning an element to focus by default
150
152
  */
151
- onDismiss: PropTypes.func,
153
+ defaultFocusElement?: UIElement
154
+ }
152
155
 
156
+ type ModalOwnProps = {
153
157
  /**
154
- *
155
- * A function that returns a reference to the content element
158
+ * The children to be rendered within the `<Modal />`. Children must be type of: `Modal.Header`, `Modal.Body`, `Modal.Footer`. The `Modal.Body` child is required, and they have to follow this order.
156
159
  */
157
- contentRef: PropTypes.func,
160
+ children: React.ReactNode // TODO: enforceOrder([ModalHeader, ModalBody, ModalFooter], [ModalHeader, ModalBody], [ModalBody, ModalFooter], [ModalBody])
158
161
 
159
162
  /**
160
- * An element or a function returning an element to use as the mount node
161
- * for the `<Modal />` (defaults to `document.body`)
163
+ * The size of the `<Modal />` content
162
164
  */
163
- mountNode: PropTypes.oneOfType([element, PropTypes.func]),
165
+ size?: 'auto' | 'small' | 'medium' | 'large' | 'fullscreen'
166
+
164
167
  /**
165
- * Insert the element at the 'top' of the mountNode or at the 'bottom'
168
+ * Designates the background style of the `<Modal />`
166
169
  */
167
- insertAt: PropTypes.oneOf(['bottom', 'top']),
170
+ variant?: 'default' | 'inverse'
168
171
 
169
172
  /**
170
- * An element, function returning an element, or array of elements that will not be hidden from
171
- * the screen reader when the `<Modal />` is open
173
+ *
174
+ * A function that returns a reference to the content element
175
+ */
176
+ contentRef?: (dialog: Dialog | null) => void
177
+
178
+ /**
179
+ * Constrain the Modal to the document window or its closest positioned parent
172
180
  */
181
+ constrain?: 'window' | 'parent'
182
+
183
+ /**
184
+ * Should ModalBody handle overflow with scrollbars, or fit its
185
+ * content within its own height?
186
+ */
187
+ overflow?: 'scroll' | 'fit'
188
+ } & ModalPropsForPortal &
189
+ ModalPropsForTransition &
190
+ ModalPropsForDialog
191
+
192
+ type PropKeys = keyof ModalOwnProps
193
+
194
+ type AllowedPropKeys = Readonly<Array<PropKeys>>
195
+
196
+ type ModalProps = ModalOwnProps &
197
+ WithStyleProps<ModalTheme, ModalStyle> &
198
+ OtherHTMLAttributes<ModalOwnProps>
199
+
200
+ type ModalStyle = ComponentStyle<'modal' | 'constrainContext'>
201
+
202
+ type ModalState = {
203
+ transitioning: boolean
204
+ }
205
+
206
+ const propTypes: PropValidators<PropKeys> = {
207
+ label: PropTypes.string.isRequired,
208
+ children: ChildrenPropTypes.enforceOrder(
209
+ [ModalHeader, ModalBody, ModalFooter],
210
+ [ModalHeader, ModalBody],
211
+ [ModalBody, ModalFooter],
212
+ [ModalBody]
213
+ ),
214
+ as: PropTypes.elementType,
215
+ size: PropTypes.oneOf(['auto', 'small', 'medium', 'large', 'fullscreen']),
216
+ variant: PropTypes.oneOf(['default', 'inverse']),
217
+ open: PropTypes.bool,
218
+ defaultFocusElement: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
219
+ shouldReturnFocus: PropTypes.bool,
220
+ shouldCloseOnDocumentClick: PropTypes.bool,
221
+ onOpen: PropTypes.func,
222
+ onClose: PropTypes.func,
223
+ onDismiss: PropTypes.func,
224
+ contentRef: PropTypes.func,
225
+ mountNode: PropTypes.oneOfType([element, PropTypes.func]),
226
+ insertAt: PropTypes.oneOf(['bottom', 'top']),
173
227
  liveRegion: PropTypes.oneOfType([
174
228
  PropTypes.arrayOf(PropTypes.element),
175
229
  PropTypes.element,
176
230
  PropTypes.func
177
231
  ]),
178
-
179
232
  transition: transitionTypePropType,
180
-
181
- /**
182
- * Callback fired before the <Modal /> transitions in
183
- */
184
233
  onEnter: PropTypes.func,
185
- /**
186
- * Callback fired as the <Modal /> begins to transition in
187
- */
188
234
  onEntering: PropTypes.func,
189
- /**
190
- * Callback fired after the <Modal /> finishes transitioning in
191
- */
192
235
  onEntered: PropTypes.func,
193
- /**
194
- * Callback fired right before the <Modal /> transitions out
195
- */
196
236
  onExit: PropTypes.func,
197
- /**
198
- * Callback fired as the <Modal /> begins to transition out
199
- */
200
237
  onExiting: PropTypes.func,
201
- /**
202
- * Callback fired after the <Modal /> finishes transitioning out
203
- */
204
238
  onExited: PropTypes.func,
205
- /**
206
- * Constrain the Modal to the document window or its closest positioned parent
207
- */
208
239
  constrain: PropTypes.oneOf(['window', 'parent']),
209
- /**
210
- * Should ModalBody handle overflow with scrollbars, or fit its
211
- * content within its own height?
212
- */
213
240
  overflow: PropTypes.oneOf(['scroll', 'fit'])
214
241
  }
215
242
 
@@ -241,5 +268,12 @@ const allowedProps: AllowedPropKeys = [
241
268
  'overflow'
242
269
  ]
243
270
 
244
- export type { ModalProps, ModalStyle }
271
+ export type {
272
+ ModalProps,
273
+ ModalStyle,
274
+ ModalState,
275
+ ModalPropsForPortal,
276
+ ModalPropsForTransition,
277
+ ModalPropsForDialog
278
+ }
245
279
  export { propTypes, allowedProps }