@codeleap/web 3.25.5 → 3.26.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/web",
3
- "version": "3.25.5",
3
+ "version": "3.26.0",
4
4
  "main": "src/index.ts",
5
5
  "repository": {
6
6
  "url": "https://github.com/codeleap-uk/internal-libs-monorepo.git",
@@ -14,7 +14,7 @@ import {
14
14
  useIsomorphicEffect,
15
15
  } from '@codeleap/common'
16
16
 
17
- import React, { useId, useRef } from 'react'
17
+ import React, { useCallback, useId, useRef } from 'react'
18
18
  import ReactDOM from 'react-dom'
19
19
  import { v4 } from 'uuid'
20
20
  import { View } from '../View'
@@ -26,6 +26,7 @@ import { Scroll } from '../Scroll'
26
26
  import { ComponentCommonProps } from '../../types'
27
27
  import { Touchable, TouchableProps } from '../Touchable'
28
28
  import { modalScrollLock, ModalStore } from '../../lib/tools/modal'
29
+ import { AnimatePresence } from 'framer-motion'
29
30
 
30
31
  export * from './styles'
31
32
 
@@ -190,6 +191,7 @@ export const ModalContent = (
190
191
  ...props
191
192
  } = modalProps
192
193
 
194
+ // const mountedVisible = useRef(visible).current
193
195
  const index = ModalStore(store => (store.indexes?.[modalId] ?? 0))
194
196
 
195
197
  const id = useId()
@@ -200,7 +202,7 @@ export const ModalContent = (
200
202
  styles,
201
203
  })
202
204
 
203
- const toggleAndReturn = () => {
205
+ const toggleAndReturn = useCallback(() => {
204
206
  toggle?.()
205
207
 
206
208
  if (alterHistory) {
@@ -208,7 +210,7 @@ export const ModalContent = (
208
210
  }
209
211
 
210
212
  if (TypeGuards.isFunction(onClose)) onClose()
211
- }
213
+ }, [toggle, onClose, alterHistory])
212
214
 
213
215
  function closeOnEscPress(e: React.KeyboardEvent<HTMLDivElement>) {
214
216
  if (!closeOnEscape) return null
@@ -256,7 +258,12 @@ export const ModalContent = (
256
258
  if (modal) modal.focus()
257
259
  }, [id])
258
260
 
259
- const close = (closable && dismissOnBackdrop) ? toggleAndReturn : () => { }
261
+ const close = useCallback(() => {
262
+ console.log('close')
263
+ if (closable && dismissOnBackdrop) {
264
+ toggleAndReturn()
265
+ }
266
+ }, [closable, dismissOnBackdrop, toggleAndReturn])
260
267
 
261
268
  const ModalBody = renderModalBody || (scroll ? Scroll : View)
262
269
 
@@ -266,79 +273,89 @@ export const ModalContent = (
266
273
  return TypeGuards.isNumber(zIndex) ? { zIndex } : {}
267
274
  }, [zIndex])
268
275
 
276
+ const _ModalContent = useCallback(({ children, footer }) => {
277
+ return <ModalArea css={variantStyles.innerWrapper}>
278
+ <Touchable
279
+ css={variantStyles.backdropPressable}
280
+
281
+ {...backdropProps}
282
+ onPress={close}
283
+ debounce={1000}
284
+ />
285
+
286
+ <View
287
+ component='section'
288
+ animated
289
+ initial={variantStyles['box:hidden:animation']}
290
+ exit={variantStyles['box:hidden:animation']}
291
+ animate={variantStyles['box:visible:animation']}
292
+ transition={variantStyles['box:transition']}
293
+ css={[
294
+ variantStyles.box,
295
+ variantStyles['box:visible'],
296
+ style,
297
+ ]}
298
+ className='content'
299
+ tabIndex={0}
300
+ id={id}
301
+ aria-modal={true}
302
+ role='dialog'
303
+ aria-describedby={`${id}-title`}
304
+ aria-label='Close the modal by pressing Escape key'
305
+
306
+ {...props}
307
+ >
308
+ <ModalHeader
309
+ {...modalProps}
310
+ variantStyles={variantStyles}
311
+ id={id}
312
+ onPressClose={toggleAndReturn}
313
+ debugName={debugName}
314
+ />
315
+
316
+ <ModalBody
317
+ css={variantStyles.body}
318
+ variantStyles={variantStyles}
319
+ id={id}
320
+ >
321
+ {children}
322
+ </ModalBody>
323
+
324
+ {footer && (
325
+ <View component='footer' css={variantStyles.footer}>
326
+ {footer}
327
+ </View>
328
+ )}
329
+ </View>
330
+ </ModalArea>
331
+ }, [close])
332
+
269
333
  return (
270
334
  <View
335
+
271
336
  ref={modalRef}
272
337
  aria-hidden={!visible}
273
338
  css={[
274
339
  variantStyles.wrapper,
275
- visible
276
- ? variantStyles['wrapper:visible']
277
- : variantStyles['wrapper:hidden'],
340
+ visible ? variantStyles['wrapper:visible'] : variantStyles['wrapper:hidden'],
278
341
  autoIndex ? { zIndex: index } : {},
279
342
  _zIndex,
280
343
  ]}
281
344
  >
282
- <Overlay
283
- debugName={debugName}
284
- visible={withOverlay ? visible : false}
285
- css={[
286
- variantStyles.backdrop,
287
- visible
288
- ? variantStyles['backdrop:visible']
289
- : variantStyles['backdrop:hidden'],
290
- ]}
291
- {...overlayProps}
292
- />
293
-
294
- <ModalArea css={variantStyles.innerWrapper}>
295
- <Touchable
296
- css={variantStyles.backdropPressable}
297
- onPress={close}
298
- debounce={1000}
299
- {...backdropProps}
300
- />
301
- <View
302
- component='section'
345
+ <AnimatePresence>
346
+ <Overlay
347
+ debugName={debugName}
348
+ visible={withOverlay ? visible : false}
303
349
  css={[
304
- variantStyles.box,
305
- visible
306
- ? variantStyles['box:visible']
307
- : variantStyles['box:hidden'],
308
- style,
350
+ variantStyles.backdrop,
309
351
  ]}
310
- className='content'
311
- tabIndex={0}
312
- id={id}
313
- aria-modal={true}
314
- role='dialog'
315
- aria-describedby={`${id}-title`}
316
- aria-label='Close the modal by pressing Escape key'
317
- {...props}
318
- >
319
- <ModalHeader
320
- {...modalProps}
321
- variantStyles={variantStyles}
322
- id={id}
323
- onPressClose={toggleAndReturn}
324
- debugName={debugName}
325
- />
326
-
327
- <ModalBody
328
- css={variantStyles.body}
329
- variantStyles={variantStyles}
330
- id={id}
331
- >
332
- {children}
333
- </ModalBody>
334
-
335
- {footer && (
336
- <View component='footer' css={variantStyles.footer}>
337
- {footer}
338
- </View>
339
- )}
340
- </View>
341
- </ModalArea>
352
+ transition={variantStyles['backdrop:transition']}
353
+ {...overlayProps}
354
+ />
355
+ </AnimatePresence>
356
+ <AnimatePresence>
357
+ {visible && <_ModalContent footer={footer}>{children}</_ModalContent>}
358
+ </AnimatePresence>
342
359
  </View>
343
360
  )
344
361
  }
@@ -380,7 +397,7 @@ export const Modal = (props) => {
380
397
  }
381
398
 
382
399
  if (scrollLock) modalScrollLock(visible, modalId.current)
383
-
400
+
384
401
  if (autoIndex) {
385
402
  setTimeout(() => {
386
403
  setIndex(visible, modalId.current)
@@ -19,12 +19,12 @@ export type OverlayProps<T extends NativeHTMLElement = 'div'> = {
19
19
  export * from './styles'
20
20
 
21
21
  export const Overlay = <T extends NativeHTMLElement>(overlayProps:OverlayProps<T>) => {
22
- const {
23
- visible,
24
- responsiveVariants,
25
- variants,
26
- styles,
27
- ...props
22
+ const {
23
+ visible,
24
+ responsiveVariants,
25
+ variants,
26
+ styles,
27
+ ...props
28
28
  } = overlayProps
29
29
 
30
30
  const variantStyles = useDefaultComponentStyle('Overlay', {
@@ -37,14 +37,26 @@ export const Overlay = <T extends NativeHTMLElement>(overlayProps:OverlayProps<T
37
37
 
38
38
  const Component = props.onClick || props.onPress ? Touchable : View
39
39
 
40
+ if (!visible) return null
40
41
  return (
41
42
  // @ts-ignore
42
43
  <Component
44
+ animated
45
+ initial={variantStyles['wrapper:animation:hidden']}
46
+ exit={variantStyles['wrapper:animation:hidden']}
47
+ animate={variantStyles['wrapper:animation:visible']}
43
48
  css={[
44
- { transition: 'opacity 0.2s ease' },
49
+
45
50
  variantStyles.wrapper,
46
- visible ? variantStyles['wrapper:visible'] : {},
51
+ visible ? variantStyles['wrapper:visible'] : variantStyles['wrapper:hidden'],
52
+ { pointerEvents: 'none' },
47
53
  ]}
54
+ transition={{
55
+
56
+ type: 'tween',
57
+ duration: 0.5,
58
+ ease: 'easeIn',
59
+ }}
48
60
  {...props}
49
61
  />
50
62
  )
@@ -421,7 +421,7 @@ export const Select = forwardRef<HTMLInputElement, SelectProps>(
421
421
  tabSelectsValue={false}
422
422
  tabIndex={0}
423
423
  backspaceRemovesValue={true}
424
- menuPortalTarget={document.body}
424
+ menuPortalTarget={typeof document === 'undefined' ? undefined : document.body}
425
425
  {...otherProps}
426
426
  {..._props}
427
427
  onKeyDown={isFocused ? handleKeyDown : null}