agroptima-design-system 0.31.7 → 0.31.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agroptima-design-system",
3
- "version": "0.31.7",
3
+ "version": "0.31.8",
4
4
  "scripts": {
5
5
  "dev": "npm run storybook",
6
6
  "storybook": "storybook dev -p 6006 --ci",
@@ -27,6 +27,21 @@ $backdrop-background-color: color_alias.$neutral-color-900;
27
27
  overflow-x: hidden;
28
28
  overflow-y: auto;
29
29
  outline: 0;
30
+ border: 0px;
31
+ background-color: transparent;
32
+ margin: 0 auto;
33
+
34
+ &::backdrop {
35
+ opacity: $backdrop-opacity;
36
+ position: fixed;
37
+ top: 0;
38
+ left: 0;
39
+ z-index: depth.$z-modal;
40
+ width: 100vw;
41
+ height: 100vh;
42
+ background-color: $backdrop-background-color;
43
+ transition: opacity 0.15s linear;
44
+ }
30
45
  }
31
46
 
32
47
  .modal-dialog {
@@ -88,18 +103,6 @@ $backdrop-background-color: color_alias.$neutral-color-900;
88
103
  gap: config.$space-2x;
89
104
  }
90
105
 
91
- .modal-backdrop {
92
- opacity: $backdrop-opacity;
93
- position: fixed;
94
- top: 0;
95
- left: 0;
96
- z-index: depth.$z-modal;
97
- width: 100vw;
98
- height: 100vh;
99
- background-color: $backdrop-background-color;
100
- transition: opacity 0.15s linear;
101
- }
102
-
103
106
  .modal-details {
104
107
  .modal-dialog {
105
108
  max-width: 50rem;
@@ -26,6 +26,7 @@ export interface ModalProps {
26
26
  variant?: Variant
27
27
  scrollable?: boolean
28
28
  className?: string
29
+ isOpen?: boolean
29
30
  onClose?: () => void
30
31
  buttons: ButtonProps[]
31
32
  children: ReactNode
@@ -43,6 +44,7 @@ export function Modal({
43
44
  id,
44
45
  title,
45
46
  buttons,
47
+ isOpen = true,
46
48
  onClose,
47
49
  children,
48
50
  variant = 'details',
@@ -54,6 +56,7 @@ export function Modal({
54
56
  <ModalDialog
55
57
  aria-labelledby={`${id}-title`}
56
58
  aria-describedby={`${id}-body`}
59
+ isOpen={isOpen}
57
60
  onClose={onClose}
58
61
  details={isDetails}
59
62
  {...props}
@@ -1,9 +1,11 @@
1
1
  'use client'
2
2
  import './Modal.scss'
3
- import React, { use, useEffect } from 'react'
3
+ import React, { useEffect, useRef } from 'react'
4
4
  import { classNames } from '../../utils/classNames'
5
5
 
6
- export interface ModalDialogProps extends React.HTMLAttributes<HTMLDivElement> {
6
+ export interface ModalDialogProps
7
+ extends React.HTMLAttributes<HTMLDialogElement> {
8
+ isOpen?: boolean
7
9
  onClose?: () => void
8
10
  details?: boolean
9
11
  scrollable?: boolean
@@ -11,12 +13,14 @@ export interface ModalDialogProps extends React.HTMLAttributes<HTMLDivElement> {
11
13
 
12
14
  export function ModalDialog({
13
15
  className,
16
+ isOpen = true,
14
17
  onClose,
15
18
  children,
16
19
  details = false,
17
20
  scrollable = false,
18
21
  ...props
19
22
  }: ModalDialogProps) {
23
+ const dialogRef = useRef<HTMLDialogElement>(null)
20
24
  const handleClick = (event: React.MouseEvent) => {
21
25
  if (event.target !== event.currentTarget) return
22
26
  onClose?.()
@@ -33,36 +37,28 @@ export function ModalDialog({
33
37
  }, [])
34
38
 
35
39
  useEffect(() => {
36
- const handleKeyDown = (event: KeyboardEvent) => {
37
- if (event.key === 'Escape') {
38
- onClose?.()
39
- }
40
+ if (isOpen) {
41
+ dialogRef.current?.showModal()
42
+ } else {
43
+ dialogRef.current?.close()
40
44
  }
41
- document.addEventListener('keydown', handleKeyDown)
42
-
43
- return () => {
44
- document.removeEventListener('keydown', handleKeyDown)
45
- }
46
- }, [onClose])
45
+ }, [isOpen])
47
46
 
48
47
  return (
49
- <>
50
- <div className="modal-backdrop"></div>
48
+ <dialog
49
+ ref={dialogRef}
50
+ className={classNames('modal', className, { 'modal-details': details })}
51
+ onClick={handleClick}
52
+ {...props}
53
+ >
51
54
  <div
52
- role="dialog"
53
- className={classNames('modal', className, { 'modal-details': details })}
54
- onClick={handleClick}
55
- {...props}
55
+ className={classNames('modal-dialog', {
56
+ 'modal-dialog-scrollable': scrollable,
57
+ })}
56
58
  >
57
- <div
58
- className={classNames('modal-dialog', {
59
- 'modal-dialog-scrollable': scrollable,
60
- })}
61
- >
62
- <div className="modal-content">{children}</div>
63
- </div>
59
+ <div className="modal-content">{children}</div>
64
60
  </div>
65
- </>
61
+ </dialog>
66
62
  )
67
63
  }
68
64
 
@@ -4,6 +4,10 @@ import { Meta } from "@storybook/blocks";
4
4
 
5
5
  # Changelog
6
6
 
7
+ ## 0.31.8
8
+
9
+ * Refactor Modal component to use HTML dialog
10
+
7
11
  ## 0.31.7
8
12
 
9
13
  * Fixed date clearing event in range and added a new translation to the footer for the first day of the selected range.
@@ -30,12 +30,16 @@ const meta = {
30
30
  docs: {
31
31
  description: {
32
32
  component:
33
- "<h2>Usage guidelines</h2><p>Modal component is used when requiring users to interact with the application, but without jumping to a new page and interrupting the user's workflow. It creates a new floating layer over the current page to get user feedback or display information.</p><ul><li>Require a response from the user</li><li>Notify the user of any related information</li><li>Confirm a user decision</li></ul>",
33
+ "<h2>Usage guidelines</h2><p>Modal component is used when requiring users to interact with the application, but without jumping to a new page and interrupting the user's workflow. It creates a new floating layer over the current page to get user feedback or display information.</p><ul><li>Require a response from the user</li><li>Notify the user of any related information</li><li>Confirm a user decision</li><li>It's opened/closed through `isOpen` prop. If we don't want it to be part of the DOM, we can also add a conditional render on the frontend project.</li><li>Natively, focus is set on the first nested focusable element and explicitly indicated by default by the browser</li><li>When nesting a Form inside Modal component, remember to add `type='button'` to all Cancel buttons to not to be considered as submitable</li></ul>",
34
34
  },
35
35
  },
36
36
  figmaPrimaryDesign,
37
37
  },
38
38
  tags: ['autodocs'],
39
+ args: {
40
+ children: 'Modal',
41
+ isOpen: false,
42
+ },
39
43
  argTypes: {
40
44
  id: {
41
45
  description: 'Id for aria purposes',
@@ -60,242 +64,243 @@ const meta = {
60
64
 
61
65
  export default meta
62
66
 
67
+ const OpenAndCloseInfo = () => {
68
+ const [isOpen, setIsOpen] = React.useState(false)
69
+
70
+ return (
71
+ <>
72
+ <Modal
73
+ id="info-dangerous-alone"
74
+ isOpen={isOpen}
75
+ variant="info"
76
+ title="It's dangerous to go alone!"
77
+ buttons={[
78
+ {
79
+ label: 'Done',
80
+ onClick: () => alert('click'),
81
+ },
82
+ ]}
83
+ >
84
+ Take this 🗡️
85
+ </Modal>
86
+ <Button label="Open Modal" onClick={() => setIsOpen(true)} />
87
+ </>
88
+ )
89
+ }
90
+
63
91
  export const Info = {
64
- render: () => (
65
- <Modal
66
- id="info-dangerous-alone"
67
- variant="info"
68
- title="It's dangerous to go alone!"
69
- buttons={[
70
- {
71
- label: 'Done',
72
- onClick: () => alert('click'),
73
- },
74
- ]}
75
- >
76
- Take this 🗡️
77
- </Modal>
78
- ),
92
+ render: () => {
93
+ return <OpenAndCloseInfo />
94
+ },
95
+ }
96
+
97
+ const OpenAndCloseSuccess = () => {
98
+ const [isOpen, setIsOpen] = React.useState(false)
99
+
100
+ return (
101
+ <>
102
+ <Modal
103
+ id="success-dangerous-alone"
104
+ isOpen={isOpen}
105
+ variant="success"
106
+ title="It's dangerous to go alone!"
107
+ buttons={[
108
+ {
109
+ label: 'Done',
110
+ onClick: () => alert('click'),
111
+ },
112
+ ]}
113
+ >
114
+ Take this 🗡️
115
+ </Modal>
116
+ <Button label="Open Modal" onClick={() => setIsOpen(true)} />
117
+ </>
118
+ )
79
119
  }
80
120
 
81
121
  export const Success = {
82
- render: () => (
83
- <Modal
84
- id="success-dangerous-alone"
85
- variant="success"
86
- title="It's dangerous to go alone!"
87
- buttons={[
88
- {
89
- label: 'Done',
90
- onClick: () => alert('click'),
91
- },
92
- ]}
93
- >
94
- Take this 🗡️
95
- </Modal>
96
- ),
122
+ render: () => {
123
+ return <OpenAndCloseSuccess />
124
+ },
125
+ }
126
+
127
+ const OpenAndCloseWarning = () => {
128
+ const [isOpen, setIsOpen] = React.useState(false)
129
+
130
+ return (
131
+ <>
132
+ <Modal
133
+ id="warning-dangerous-alone"
134
+ isOpen={isOpen}
135
+ variant="warning"
136
+ title="It's dangerous to go alone!"
137
+ buttons={[
138
+ {
139
+ label: 'Done',
140
+ onClick: () => alert('click'),
141
+ },
142
+ ]}
143
+ >
144
+ Take this 🗡️
145
+ </Modal>
146
+ <Button label="Open Modal" onClick={() => setIsOpen(true)} />
147
+ </>
148
+ )
97
149
  }
98
150
 
99
151
  export const Warning = {
100
- render: () => (
101
- <Modal
102
- id="warning-dangerous-alone"
103
- variant="warning"
104
- title="It's dangerous to go alone!"
105
- buttons={[
106
- {
107
- label: 'Done',
108
- onClick: () => alert('click'),
109
- },
110
- ]}
111
- >
112
- Take this 🗡️
113
- </Modal>
114
- ),
152
+ render: () => {
153
+ return <OpenAndCloseWarning />
154
+ },
115
155
  }
116
156
 
117
- export const Error = {
118
- render: () => (
119
- <Modal
120
- id="error-dangerous-alone"
121
- variant="error"
122
- title="It's dangerous to go alone!"
123
- buttons={[
124
- {
125
- label: 'Done',
126
- onClick: () => alert('click'),
127
- },
128
- ]}
129
- >
130
- Take this 🗡️
131
- </Modal>
132
- ),
157
+ const OpenAndCloseError = () => {
158
+ const [isOpen, setIsOpen] = React.useState(false)
159
+
160
+ return (
161
+ <>
162
+ <Modal
163
+ id="error-dangerous-alone"
164
+ isOpen={isOpen}
165
+ variant="error"
166
+ title="It's dangerous to go alone!"
167
+ buttons={[
168
+ {
169
+ label: 'Done',
170
+ onClick: () => alert('click'),
171
+ },
172
+ ]}
173
+ >
174
+ Take this 🗡️
175
+ </Modal>
176
+ <Button label="Open Modal" onClick={() => setIsOpen(true)} />
177
+ </>
178
+ )
133
179
  }
134
180
 
135
- export const DeleteOrDiscard = {
136
- render: () => (
137
- <Modal
138
- id="discard-dangerous-alone"
139
- variant="discard"
140
- title="The far horizon was always steamy and indistinct"
141
- buttons={[
142
- {
143
- label: 'Cancel',
144
- variant: 'neutral',
145
- onClick: () => alert('click'),
146
- },
147
- {
148
- label: 'Delete',
149
- variant: 'error',
150
- onClick: () => alert('click'),
151
- },
152
- ]}
153
- >
154
- But I could see that great jungles of unknown tree-ferns, calamites,
155
- lepidodendra, and sigillaria lay outside the city, their fantastic
156
- frondage waving mockingly in the shifting vapours. Now and then there
157
- would be suggestions of motion in the sky, but these my early visions
158
- never resolved.
159
- </Modal>
160
- ),
181
+ export const Error = {
182
+ render: () => {
183
+ return <OpenAndCloseError />
184
+ },
161
185
  }
162
186
 
163
- export const LargeModal = () => (
164
- <Modal
165
- title="Large Modal"
166
- onClose={() => alert('Close')}
167
- buttons={[
168
- { label: 'Close', variant: 'neutral', onClick: () => alert('Close') },
169
- { label: 'Save' },
170
- ]}
171
- >
172
- <LoremIpsum lorems={10} />
173
- <Select
174
- id="select"
175
- label="Select"
176
- helpText="This is a help text"
177
- placeholder="Select an option"
178
- options={[
179
- { id: '1', label: 'Option 1' },
180
- { id: '2', label: 'Option 2' },
181
- { id: '3', label: 'Option 3' },
182
- { id: '4', label: 'Option 4' },
183
- { id: '5', label: 'Option 5' },
184
- { id: '6', label: 'Option 6' },
185
- { id: '7', label: 'Option 7' },
186
- { id: '8', label: 'Option 8' },
187
- { id: '9', label: 'Option 9' },
188
- { id: '10', label: 'Option 10' },
189
- { id: '11', label: 'Option 11' },
190
- { id: '12', label: 'Option 12' },
191
- { id: '13', label: 'Option 13' },
192
- { id: '14', label: 'Option 14' },
193
- { id: '15', label: 'Option 15' },
194
- ]}
195
- />
196
- </Modal>
197
- )
187
+ const OpenAndCloseDeleteOrDiscard = () => {
188
+ const [isOpen, setIsOpen] = React.useState(false)
198
189
 
199
- export const ScrollableModal = () => (
200
- <Modal
201
- title="Scrollable Modal Title"
202
- onClose={() => console.log('close')}
203
- scrollable
204
- buttons={[
205
- {
206
- label: 'Close',
207
- variant: 'neutral',
208
- onClick: () => console.log('close'),
209
- },
210
- ]}
211
- >
212
- <LoremIpsum lorems={10} />
213
- <Select
214
- id="select"
215
- label="Select"
216
- helpText="This is a help text"
217
- placeholder="Select an option"
218
- options={[
219
- { id: '1', label: 'Option 1' },
220
- { id: '2', label: 'Option 2' },
221
- { id: '3', label: 'Option 3' },
222
- { id: '4', label: 'Option 4' },
223
- { id: '5', label: 'Option 5' },
224
- { id: '6', label: 'Option 6' },
225
- { id: '7', label: 'Option 7' },
226
- { id: '8', label: 'Option 8' },
227
- { id: '9', label: 'Option 9' },
228
- { id: '10', label: 'Option 10' },
229
- { id: '11', label: 'Option 11' },
230
- { id: '12', label: 'Option 12' },
231
- { id: '13', label: 'Option 13' },
232
- { id: '14', label: 'Option 14' },
233
- { id: '15', label: 'Option 15' },
234
- ]}
235
- />
236
- </Modal>
237
- )
190
+ return (
191
+ <>
192
+ <Modal
193
+ id="discard-dangerous-alone"
194
+ isOpen={isOpen}
195
+ variant="discard"
196
+ title="The far horizon was always steamy and indistinct"
197
+ buttons={[
198
+ {
199
+ label: 'Cancel',
200
+ variant: 'neutral',
201
+ onClick: () => alert('click'),
202
+ },
203
+ {
204
+ label: 'Delete',
205
+ variant: 'error',
206
+ onClick: () => alert('click'),
207
+ },
208
+ ]}
209
+ >
210
+ But I could see that great jungles of unknown tree-ferns, calamites,
211
+ lepidodendra, and sigillaria lay outside the city, their fantastic
212
+ frondage waving mockingly in the shifting vapours. Now and then there
213
+ would be suggestions of motion in the sky, but these my early visions
214
+ never resolved.
215
+ </Modal>
216
+ <Button label="Open Modal" onClick={() => setIsOpen(true)} />
217
+ </>
218
+ )
219
+ }
238
220
 
239
- const OpenAndCloseModalComponent = () => {
221
+ export const DeleteOrDiscard = {
222
+ render: () => {
223
+ return <OpenAndCloseDeleteOrDiscard />
224
+ },
225
+ }
226
+
227
+ const OpenAndCloseLargeModal = () => {
240
228
  const [isOpen, setIsOpen] = React.useState(false)
241
- const closeModal = () => setIsOpen(false)
229
+
242
230
  return (
243
231
  <>
244
- {isOpen && (
245
- <ModalDialog details onClose={closeModal}>
246
- <ModalHeader>
247
- <ModalTitle>Modal title</ModalTitle>
248
- <ModalCloseButton onClick={closeModal} />
249
- </ModalHeader>
250
- <ModalBody>
251
- <LoremIpsum lorems={1} />
252
- </ModalBody>
253
- <ModalFooter>
254
- <Button label="Close" onClick={closeModal} />
255
- </ModalFooter>
256
- </ModalDialog>
257
- )}
258
- <LoremIpsum lorems={10} />
259
- <br />
260
- <hr />
261
- <br />
232
+ <Modal
233
+ title="Large Modal"
234
+ isOpen={isOpen}
235
+ onClose={() => alert('Close')}
236
+ buttons={[
237
+ {
238
+ label: 'Close',
239
+ type: 'button',
240
+ variant: 'neutral',
241
+ onClick: () => alert('Close'),
242
+ },
243
+ { label: 'Save' },
244
+ ]}
245
+ >
246
+ <LoremIpsum lorems={10} />
247
+ <Select
248
+ id="select"
249
+ label="Select"
250
+ helpText="This is a help text"
251
+ placeholder="Select an option"
252
+ options={[
253
+ { id: '1', label: 'Option 1' },
254
+ { id: '2', label: 'Option 2' },
255
+ { id: '3', label: 'Option 3' },
256
+ { id: '4', label: 'Option 4' },
257
+ { id: '5', label: 'Option 5' },
258
+ { id: '6', label: 'Option 6' },
259
+ { id: '7', label: 'Option 7' },
260
+ { id: '8', label: 'Option 8' },
261
+ { id: '9', label: 'Option 9' },
262
+ { id: '10', label: 'Option 10' },
263
+ { id: '11', label: 'Option 11' },
264
+ { id: '12', label: 'Option 12' },
265
+ { id: '13', label: 'Option 13' },
266
+ { id: '14', label: 'Option 14' },
267
+ { id: '15', label: 'Option 15' },
268
+ ]}
269
+ />
270
+ </Modal>
262
271
  <Button label="Open Modal" onClick={() => setIsOpen(true)} />
263
272
  </>
264
273
  )
265
274
  }
266
275
 
267
- export const OpenAndCloseModal = {
276
+ export const LargeModal = {
268
277
  render: () => {
269
- return <OpenAndCloseModalComponent />
278
+ return <OpenAndCloseLargeModal />
270
279
  },
271
280
  }
272
281
 
273
- export const FormModal = () => (
274
- <form
275
- onSubmit={(e) => {
276
- e.preventDefault()
277
- const formData = new FormData(e.currentTarget)
278
- alert(`Form submitted: ${JSON.stringify(Object.fromEntries(formData))}`)
279
- }}
280
- >
281
- <Modal
282
- title="Form Modal"
283
- onClose={() => alert('Close')}
284
- buttons={[
285
- {
286
- label: 'Close',
287
- type: 'button',
288
- variant: 'neutral',
289
- onClick: () => alert('Close'),
290
- },
291
- { label: 'Save', type: 'submit' },
292
- ]}
293
- >
294
- <FormContainer fluid>
295
- <Input name="input" label="Input" placeholder="Type something" />
282
+ const OpenAndCloseScrollableModal = () => {
283
+ const [isOpen, setIsOpen] = React.useState(false)
284
+
285
+ return (
286
+ <>
287
+ <Modal
288
+ title="Scrollable Modal Title"
289
+ isOpen={isOpen}
290
+ onClose={() => console.log('close')}
291
+ scrollable
292
+ buttons={[
293
+ {
294
+ label: 'Close',
295
+ variant: 'neutral',
296
+ onClick: () => console.log('close'),
297
+ },
298
+ ]}
299
+ >
300
+ <LoremIpsum lorems={10} />
296
301
  <Select
302
+ id="select"
297
303
  label="Select"
298
- name="select"
299
304
  helpText="This is a help text"
300
305
  placeholder="Select an option"
301
306
  options={[
@@ -316,7 +321,117 @@ export const FormModal = () => (
316
321
  { id: '15', label: 'Option 15' },
317
322
  ]}
318
323
  />
319
- </FormContainer>
320
- </Modal>
321
- </form>
322
- )
324
+ </Modal>
325
+ <Button label="Open Modal" onClick={() => setIsOpen(true)} />
326
+ </>
327
+ )
328
+ }
329
+
330
+ export const ScrollableModal = {
331
+ render: () => {
332
+ return <OpenAndCloseScrollableModal />
333
+ },
334
+ }
335
+
336
+ const OpenAndCloseModalComponent = () => {
337
+ const [isOpen, setIsOpen] = React.useState(false)
338
+ const closeModal = () => setIsOpen(false)
339
+ return (
340
+ <>
341
+ <ModalDialog isOpen={isOpen} details onClose={closeModal}>
342
+ <ModalHeader>
343
+ <ModalTitle>Modal title</ModalTitle>
344
+ <ModalCloseButton onClick={closeModal} />
345
+ </ModalHeader>
346
+ <ModalBody>
347
+ <LoremIpsum lorems={1} />
348
+ </ModalBody>
349
+ <ModalFooter>
350
+ <Button label="Close" onClick={closeModal} />
351
+ </ModalFooter>
352
+ </ModalDialog>
353
+
354
+ <LoremIpsum lorems={10} />
355
+ <br />
356
+ <hr />
357
+ <br />
358
+ <Button label="Open Modal" onClick={() => setIsOpen(true)} />
359
+ </>
360
+ )
361
+ }
362
+
363
+ export const OpenAndCloseModal = {
364
+ render: () => {
365
+ return <OpenAndCloseModalComponent />
366
+ },
367
+ }
368
+
369
+ const OpenAndCloseFormModal = () => {
370
+ const [isOpen, setIsOpen] = React.useState(false)
371
+
372
+ return (
373
+ <form
374
+ onSubmit={(e) => {
375
+ e.preventDefault()
376
+ const formData = new FormData(e.currentTarget)
377
+ alert(
378
+ `Form submitted: ${JSON.stringify(Object.fromEntries(formData))}`,
379
+ )
380
+ }}
381
+ >
382
+ <Modal
383
+ isOpen={isOpen}
384
+ title="Form Modal"
385
+ onClose={() => alert('Close')}
386
+ buttons={[
387
+ {
388
+ label: 'Close',
389
+ type: 'button',
390
+ variant: 'neutral',
391
+ onClick: () => alert('Close'),
392
+ },
393
+ { label: 'Save', type: 'submit' },
394
+ ]}
395
+ >
396
+ <FormContainer fluid>
397
+ <Input name="input" label="Input" placeholder="Type something" />
398
+ <Select
399
+ label="Select"
400
+ name="select"
401
+ helpText="This is a help text"
402
+ placeholder="Select an option"
403
+ options={[
404
+ { id: '1', label: 'Option 1' },
405
+ { id: '2', label: 'Option 2' },
406
+ { id: '3', label: 'Option 3' },
407
+ { id: '4', label: 'Option 4' },
408
+ { id: '5', label: 'Option 5' },
409
+ { id: '6', label: 'Option 6' },
410
+ { id: '7', label: 'Option 7' },
411
+ { id: '8', label: 'Option 8' },
412
+ { id: '9', label: 'Option 9' },
413
+ { id: '10', label: 'Option 10' },
414
+ { id: '11', label: 'Option 11' },
415
+ { id: '12', label: 'Option 12' },
416
+ { id: '13', label: 'Option 13' },
417
+ { id: '14', label: 'Option 14' },
418
+ { id: '15', label: 'Option 15' },
419
+ ]}
420
+ />
421
+ </FormContainer>
422
+ </Modal>
423
+
424
+ <Button
425
+ label="Open Modal"
426
+ type="button"
427
+ onClick={() => setIsOpen(true)}
428
+ />
429
+ </form>
430
+ )
431
+ }
432
+
433
+ export const FormModal = {
434
+ render: () => {
435
+ return <OpenAndCloseFormModal />
436
+ },
437
+ }
@@ -3,6 +3,12 @@ import React from 'react'
3
3
  import { Modal, type Variant } from '../src/atoms/Modal'
4
4
 
5
5
  describe('Modal', () => {
6
+ beforeAll(() => {
7
+ HTMLDialogElement.prototype.show = jest.fn()
8
+ HTMLDialogElement.prototype.showModal = jest.fn()
9
+ HTMLDialogElement.prototype.close = jest.fn()
10
+ })
11
+
6
12
  const variants = ['info', 'success', 'warning', 'error']
7
13
  it.each(variants)(
8
14
  'renders the %s variant with title and the expected icon and button',
@@ -14,6 +20,7 @@ describe('Modal', () => {
14
20
  variant={variant as Variant}
15
21
  id={`${variant}-modal`}
16
22
  title={title}
23
+ isOpen={true}
17
24
  buttons={[
18
25
  {
19
26
  label: 'Done',
@@ -23,11 +30,11 @@ describe('Modal', () => {
23
30
  {content}
24
31
  </Modal>,
25
32
  )
26
- expect(getByRole('img')).toHaveClass(variant)
33
+ expect(getByRole('img', { hidden: true })).toHaveClass(variant)
27
34
  expect(getByText(title)).toBeInTheDocument()
28
35
  expect(getByText(content)).toBeInTheDocument()
29
- expect(getByRole('button')).toHaveTextContent('Done')
30
- expect(getByRole('button')).toHaveClass('primary')
36
+ expect(getByRole('button', { hidden: true })).toHaveTextContent('Done')
37
+ expect(getByRole('button', { hidden: true })).toHaveClass('primary')
31
38
  },
32
39
  )
33
40
 
@@ -39,6 +46,7 @@ describe('Modal', () => {
39
46
  id="discard-modal"
40
47
  title={title}
41
48
  variant="discard"
49
+ isOpen={true}
42
50
  buttons={[
43
51
  {
44
52
  label: 'Cancel',
@@ -53,12 +61,20 @@ describe('Modal', () => {
53
61
  {content}
54
62
  </Modal>,
55
63
  )
56
- expect(getByRole('img')).toHaveClass('warning')
64
+ expect(getByRole('img', { hidden: true })).toHaveClass('warning')
57
65
  expect(getByText(title)).toBeInTheDocument()
58
66
  expect(getByText(content)).toBeInTheDocument()
59
- expect(screen.getAllByRole('button')[0]).toHaveTextContent('Cancel')
60
- expect(screen.getAllByRole('button')[0]).toHaveClass('neutral')
61
- expect(screen.getAllByRole('button')[1]).toHaveTextContent('Delete')
62
- expect(screen.getAllByRole('button')[1]).toHaveClass('error')
67
+ expect(
68
+ screen.getAllByRole('button', { hidden: true })[0],
69
+ ).toHaveTextContent('Cancel')
70
+ expect(screen.getAllByRole('button', { hidden: true })[0]).toHaveClass(
71
+ 'neutral',
72
+ )
73
+ expect(
74
+ screen.getAllByRole('button', { hidden: true })[1],
75
+ ).toHaveTextContent('Delete')
76
+ expect(screen.getAllByRole('button', { hidden: true })[1]).toHaveClass(
77
+ 'error',
78
+ )
63
79
  })
64
80
  })
@@ -13,6 +13,11 @@ const stories = Object.values(components).map((component) => {
13
13
  })
14
14
 
15
15
  stories.forEach(({ title, stories }) => {
16
+ beforeAll(() => {
17
+ HTMLDialogElement.prototype.show = jest.fn()
18
+ HTMLDialogElement.prototype.showModal = jest.fn()
19
+ HTMLDialogElement.prototype.close = jest.fn()
20
+ })
16
21
  const variations = Object.entries(stories)
17
22
 
18
23
  variations.forEach(([variationName, story]: [string, any]) => {