@tamagui/sheet 1.26.1 → 1.27.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.
Files changed (53) hide show
  1. package/dist/cjs/Sheet.js +23 -425
  2. package/dist/cjs/Sheet.js.map +2 -2
  3. package/dist/cjs/StyledSheet.js +132 -0
  4. package/dist/cjs/StyledSheet.js.map +6 -0
  5. package/dist/cjs/constants.js +3 -0
  6. package/dist/cjs/constants.js.map +1 -1
  7. package/dist/cjs/createSheet.js +439 -0
  8. package/dist/cjs/createSheet.js.map +6 -0
  9. package/dist/cjs/index.js +2 -0
  10. package/dist/cjs/index.js.map +1 -1
  11. package/dist/esm/Sheet.js +20 -447
  12. package/dist/esm/Sheet.js.map +2 -2
  13. package/dist/esm/StyledSheet.js +100 -0
  14. package/dist/esm/StyledSheet.js.map +6 -0
  15. package/dist/esm/constants.js +2 -0
  16. package/dist/esm/constants.js.map +1 -1
  17. package/dist/esm/createSheet.js +441 -0
  18. package/dist/esm/createSheet.js.map +6 -0
  19. package/dist/esm/index.js +1 -0
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/jsx/Sheet.js +20 -434
  22. package/dist/jsx/Sheet.js.map +2 -2
  23. package/dist/jsx/Sheet.mjs +20 -434
  24. package/dist/jsx/Sheet.mjs.map +2 -2
  25. package/dist/jsx/StyledSheet.js +100 -0
  26. package/dist/jsx/StyledSheet.js.map +6 -0
  27. package/dist/jsx/StyledSheet.mjs +100 -0
  28. package/dist/jsx/StyledSheet.mjs.map +6 -0
  29. package/dist/jsx/constants.js +2 -0
  30. package/dist/jsx/constants.js.map +1 -1
  31. package/dist/jsx/constants.mjs +2 -0
  32. package/dist/jsx/constants.mjs.map +1 -1
  33. package/dist/jsx/createSheet.js +428 -0
  34. package/dist/jsx/createSheet.js.map +6 -0
  35. package/dist/jsx/createSheet.mjs +428 -0
  36. package/dist/jsx/createSheet.mjs.map +6 -0
  37. package/dist/jsx/index.js +1 -0
  38. package/dist/jsx/index.js.map +1 -1
  39. package/dist/jsx/index.mjs +1 -0
  40. package/dist/jsx/index.mjs.map +1 -1
  41. package/package.json +13 -13
  42. package/src/Sheet.tsx +20 -543
  43. package/src/constants.tsx +1 -0
  44. package/src/createSheet.tsx +565 -0
  45. package/src/index.ts +1 -0
  46. package/types/Sheet.d.ts +159 -80
  47. package/types/Sheet.d.ts.map +1 -1
  48. package/types/constants.d.ts +1 -0
  49. package/types/constants.d.ts.map +1 -1
  50. package/types/createSheet.d.ts +66 -0
  51. package/types/createSheet.d.ts.map +1 -0
  52. package/types/index.d.ts +1 -0
  53. package/types/index.d.ts.map +1 -1
package/src/Sheet.tsx CHANGED
@@ -1,57 +1,8 @@
1
- import { AdaptParentContext } from '@tamagui/adapt'
2
- import { useComposedRefs } from '@tamagui/compose-refs'
3
- import {
4
- GetProps,
5
- Theme,
6
- isClient,
7
- isTouchable,
8
- isWeb,
9
- mergeEvent,
10
- styled,
11
- themeable,
12
- useAnimationDriver,
13
- useDidFinishSSR,
14
- useEvent,
15
- useIsomorphicLayoutEffect,
16
- useThemeName,
17
- withStaticProperties,
18
- } from '@tamagui/core'
19
- import { Portal } from '@tamagui/portal'
20
- import { RemoveScroll } from '@tamagui/remove-scroll'
21
- import { ThemeableStack, XStack, XStackProps, YStack, YStackProps } from '@tamagui/stacks'
22
- import { useKeyboardVisible } from '@tamagui/use-keyboard-visible'
23
- import {
24
- FunctionComponent,
25
- RefAttributes,
26
- createContext,
27
- forwardRef,
28
- useCallback,
29
- useContext,
30
- useEffect,
31
- useMemo,
32
- useRef,
33
- useState,
34
- } from 'react'
35
- import {
36
- Animated,
37
- GestureResponderEvent,
38
- Keyboard,
39
- PanResponder,
40
- PanResponderGestureState,
41
- Platform,
42
- View,
43
- } from 'react-native'
1
+ import { styled } from '@tamagui/core'
2
+ import { ThemeableStack, XStack, YStack } from '@tamagui/stacks'
44
3
 
45
- import { SHEET_HANDLE_NAME, SHEET_NAME } from './constants'
46
- import { getNativeSheet } from './nativeSheet'
47
- import { SheetProvider, useSheetContext } from './SheetContext'
48
- import { SheetScrollView } from './SheetScrollView'
49
- import { SheetProps, SheetScopedProps } from './types'
50
- import { useSheetChildren } from './useSheetChildren'
51
- import { useSheetController } from './useSheetController'
52
- import { useSheetOpenState } from './useSheetOpenState'
53
- import { useSheetProviderProps } from './useSheetProviderProps'
54
- import { useSheetSnapPoints } from './useSheetSnapPoints'
4
+ import { SHEET_HANDLE_NAME, SHEET_NAME, SHEET_OVERLAY_NAME } from './constants'
5
+ import { createSheet } from './createSheet'
55
6
 
56
7
  export { createSheetScope } from './SheetContext'
57
8
  export * from './types'
@@ -60,7 +11,7 @@ export * from './types'
60
11
  * SheetHandle
61
12
  * -----------------------------------------------------------------------------------------------*/
62
13
 
63
- export const SheetHandleFrame = styled(XStack, {
14
+ export const Handle = styled(XStack, {
64
15
  name: SHEET_HANDLE_NAME,
65
16
 
66
17
  variants: {
@@ -96,41 +47,22 @@ export const SheetHandleFrame = styled(XStack, {
96
47
  },
97
48
  })
98
49
 
99
- export const SheetHandle = SheetHandleFrame.extractable(
100
- ({ __scopeSheet, ...props }: SheetScopedProps<XStackProps>) => {
101
- const context = useSheetContext(SHEET_HANDLE_NAME, __scopeSheet)
102
- return (
103
- <SheetHandleFrame
104
- onPress={() => {
105
- // don't toggle to the bottom snap position when dismissOnSnapToBottom set
106
- const max = context.snapPoints.length + (context.dismissOnSnapToBottom ? -1 : 0)
107
- const nextPos = (context.position + 1) % max
108
- context.setPosition(nextPos)
109
- }}
110
- open={context.open}
111
- {...props}
112
- />
113
- )
114
- }
115
- )
116
-
117
50
  /* -------------------------------------------------------------------------------------------------
118
51
  * SheetOverlay
119
52
  * -----------------------------------------------------------------------------------------------*/
120
53
 
121
- const SHEET_OVERLAY_NAME = 'SheetOverlay'
122
-
123
- export const SheetOverlayFrame = styled(ThemeableStack, {
54
+ export const Overlay = styled(ThemeableStack, {
124
55
  name: SHEET_OVERLAY_NAME,
125
56
 
126
57
  variants: {
127
- closed: {
58
+ open: {
128
59
  true: {
129
- opacity: 0,
130
- pointerEvents: 'none',
60
+ opacity: 1,
61
+ pointerEvents: 'auto',
131
62
  },
132
63
  false: {
133
- pointerEvents: 'auto',
64
+ opacity: 0,
65
+ pointerEvents: 'none',
134
66
  },
135
67
  },
136
68
 
@@ -149,38 +81,11 @@ export const SheetOverlayFrame = styled(ThemeableStack, {
149
81
  },
150
82
  })
151
83
 
152
- export type SheetOverlayProps = GetProps<typeof SheetOverlayFrame>
153
-
154
- export const SheetOverlay = SheetOverlayFrame.extractable(
155
- ({ __scopeSheet, ...props }: SheetScopedProps<SheetOverlayProps>) => {
156
- const context = useSheetContext(SHEET_OVERLAY_NAME, __scopeSheet)
157
- return (
158
- <SheetOverlayFrame
159
- closed={!context.open || context.hidden}
160
- {...props}
161
- onPress={mergeEvent(
162
- props.onPress as any,
163
- context.dismissOnOverlayPress
164
- ? () => {
165
- context.setOpen(false)
166
- }
167
- : undefined
168
- )}
169
- />
170
- )
171
- }
172
- )
173
-
174
84
  /* -------------------------------------------------------------------------------------------------
175
85
  * Sheet
176
86
  * -----------------------------------------------------------------------------------------------*/
177
87
 
178
- const selectionStyleSheet = isClient ? document.createElement('style') : null
179
- if (selectionStyleSheet) {
180
- document.head.appendChild(selectionStyleSheet)
181
- }
182
-
183
- export const SheetFrameFrame = styled(YStack, {
88
+ export const Frame = styled(YStack, {
184
89
  name: SHEET_NAME,
185
90
 
186
91
  variants: {
@@ -203,442 +108,14 @@ export const SheetFrameFrame = styled(YStack, {
203
108
  },
204
109
  })
205
110
 
206
- export const SheetFrame = SheetFrameFrame.extractable(
207
- forwardRef(
208
- ({ __scopeSheet, ...props }: SheetScopedProps<YStackProps>, forwardedRef) => {
209
- const context = useSheetContext(SHEET_NAME, __scopeSheet)
210
- const composedContentRef = useComposedRefs(forwardedRef, context.contentRef)
211
- return <SheetFrameFrame ref={composedContentRef} {...props} />
212
- }
213
- )
214
- )
215
-
216
- // set all the way off screen
217
- const HIDDEN_SIZE = 10_000
218
-
219
- const sheetComponents = {
220
- Handle: SheetHandle,
221
- Frame: SheetFrame,
222
- Overlay: SheetOverlay,
223
- ScrollView: SheetScrollView,
224
- }
225
-
226
- const ParentSheetContext = createContext({
227
- zIndex: 100_000,
111
+ export const Sheet = createSheet({
112
+ Frame,
113
+ Handle,
114
+ Overlay,
228
115
  })
229
116
 
230
- export const Sheet = withStaticProperties(
231
- forwardRef<View, SheetProps>(function Sheet(props, ref) {
232
- const hydrated = useDidFinishSSR()
233
- const { isShowingNonSheet } = useSheetController()
234
-
235
- let SheetImplementation = SheetImplementationCustom
236
-
237
- if (props.native && Platform.OS === 'ios') {
238
- if (process.env.TAMAGUI_TARGET === 'native') {
239
- const impl = getNativeSheet('ios')
240
- if (impl) {
241
- SheetImplementation = impl
242
- }
243
- }
244
- }
245
-
246
- /**
247
- * Performance is sensitive here so avoid all the hooks below with this
248
- */
249
- if (isShowingNonSheet || !hydrated) {
250
- return null
251
- }
252
-
253
- return <SheetImplementation ref={ref} {...props} />
254
- }),
255
- sheetComponents
256
- )
257
-
258
- const SheetImplementationCustom = themeable(
259
- forwardRef<View, SheetProps>(function SheetImplementationCustom(props, forwardedRef) {
260
- const parentSheet = useContext(ParentSheetContext)
261
-
262
- const {
263
- animationConfig,
264
- forceRemoveScrollEnabled = null,
265
- disableDrag: disableDragProp,
266
- modal = false,
267
- zIndex = parentSheet.zIndex + 1,
268
- moveOnKeyboardChange = false,
269
- portalProps,
270
- } = props
271
-
272
- const state = useSheetOpenState(props)
273
- const providerProps = useSheetProviderProps(props, state)
274
- const { positions, maxSnapPoint, screenSize } = useSheetSnapPoints(providerProps)
275
-
276
- const { position, contentRef, setPosition, scrollBridge, frameSize, setFrameSize } =
277
- providerProps
278
-
279
- const { open, isHidden, controller } = state
280
-
281
- const { frameComponent, handleComponent, bottomCoverComponent, overlayComponent } =
282
- useSheetChildren(props.children)
283
-
284
- const sheetRef = useRef<View>(null)
285
- const ref = useComposedRefs(forwardedRef, sheetRef)
286
-
287
- const driver = useAnimationDriver()
288
- if (!driver) {
289
- throw new Error('Must set animations in tamagui.config.ts')
290
- }
291
-
292
- const disableDrag = disableDragProp ?? controller?.disableDrag
293
- const keyboardIsVisible = useKeyboardVisible()
294
- const themeName = useThemeName()
295
-
296
- const { useAnimatedNumber, useAnimatedNumberReaction, useAnimatedNumberStyle } =
297
- driver
298
-
299
- const animatedNumber = useAnimatedNumber(HIDDEN_SIZE)
300
-
301
- // native only fix
302
- const at = useRef(0)
303
-
304
- useAnimatedNumberReaction(
305
- {
306
- value: animatedNumber,
307
- hostRef: sheetRef,
308
- },
309
- (value) => {
310
- if (!driver.isReactNative) return
311
- at.current = value
312
- scrollBridge.paneY = value
313
- }
314
- )
315
-
316
- function stopSpring() {
317
- animatedNumber.stop()
318
- if (scrollBridge.onFinishAnimate) {
319
- scrollBridge.onFinishAnimate()
320
- scrollBridge.onFinishAnimate = undefined
321
- }
322
- }
323
-
324
- // we need to set this *after* fully closed to 0, to avoid it overlapping
325
- // the page when resizing quickly on web for example
326
- const [opacity, setOpacity] = useState(open ? 1 : 0)
327
- if (open && opacity === 0) {
328
- setOpacity(1)
329
- }
330
- useEffect(() => {
331
- if (!open) {
332
- // need to wait for animation complete, for now lets just do it naively
333
- const tm = setTimeout(() => {
334
- setOpacity(0)
335
- }, 400)
336
- return () => {
337
- clearTimeout(tm)
338
- }
339
- }
340
- }, [open])
341
-
342
- const animateTo = useEvent((position: number) => {
343
- const current = animatedNumber.getValue()
344
- if (isHidden && open) return
345
- if (!current) return
346
- if (frameSize === 0) return
347
- const hiddenValue = frameSize === 0 ? HIDDEN_SIZE : screenSize
348
- const toValue = isHidden || position === -1 ? hiddenValue : positions[position]
349
- if (at.current === toValue) return
350
- stopSpring()
351
- if (isHidden) {
352
- animatedNumber.setValue(toValue, {
353
- type: 'timing',
354
- duration: 0,
355
- })
356
- at.current = toValue
357
- return
358
- }
359
- // dont bounce on initial measure to bottom
360
- const overshootClamping = at.current === HIDDEN_SIZE
361
- animatedNumber.setValue(toValue, {
362
- ...animationConfig,
363
- type: 'spring',
364
- overshootClamping,
365
- })
366
- })
367
-
368
- useIsomorphicLayoutEffect(() => {
369
- animateTo(position)
370
- }, [isHidden, frameSize, position, animateTo])
371
-
372
- /**
373
- * This is a hacky workaround for native:
374
- */
375
- const [isShowingInnerSheet, setIsShowingInnerSheet] = useState(false)
376
- const shouldHideParentSheet = !isWeb && modal && isShowingInnerSheet
377
- const parentSheetContext = useContext(SheetInsideSheetContext)
378
- const onInnerSheet = useCallback((hasChild: boolean) => {
379
- setIsShowingInnerSheet(hasChild)
380
- }, [])
381
-
382
- const panResponder = useMemo(
383
- () => {
384
- if (disableDrag) return
385
- if (!frameSize) return
386
- if (isShowingInnerSheet) return
387
-
388
- const minY = positions[0]
389
- scrollBridge.paneMinY = minY
390
- let startY = at.current
391
-
392
- function makeUnselectable(val: boolean) {
393
- if (!selectionStyleSheet) return
394
- if (!val) {
395
- selectionStyleSheet.innerText = ''
396
- } else {
397
- selectionStyleSheet.innerText =
398
- ':root * { user-select: none !important; -webkit-user-select: none !important; }'
399
- }
400
- }
401
-
402
- const release = ({ vy, dragAt }: { dragAt: number; vy: number }) => {
403
- isExternalDrag = false
404
- previouslyScrolling = false
405
- makeUnselectable(false)
406
- const at = dragAt + startY
407
- // seems liky vy goes up to about 4 at the very most (+ is down, - is up)
408
- // lets base our multiplier on the total layout height
409
- const end = at + frameSize * vy * 0.2
410
- let closestPoint = 0
411
- let dist = Infinity
412
- for (let i = 0; i < positions.length; i++) {
413
- const position = positions[i]
414
- const curDist = end > position ? end - position : position - end
415
- if (curDist < dist) {
416
- dist = curDist
417
- closestPoint = i
418
- }
419
- }
420
- // have to call both because state may not change but need to snap back
421
- setPosition(closestPoint)
422
- animateTo(closestPoint)
423
- }
424
-
425
- const finish = (_e: GestureResponderEvent, state: PanResponderGestureState) => {
426
- release({
427
- vy: state.vy,
428
- dragAt: state.dy,
429
- })
430
- }
431
-
432
- let previouslyScrolling = false
433
-
434
- const onMoveShouldSet = (
435
- _e: GestureResponderEvent,
436
- { dy }: PanResponderGestureState
437
- ) => {
438
- const isScrolled = scrollBridge.y !== 0
439
- const isDraggingUp = dy < 0
440
- // we can treat near top instead of exactly to avoid trouble with springs
441
- const isNearTop = scrollBridge.paneY - 5 <= scrollBridge.paneMinY
442
- if (isScrolled) {
443
- previouslyScrolling = true
444
- return false
445
- }
446
- // prevent drag once at top and pulling up
447
- if (isNearTop) {
448
- if (!isScrolled && isDraggingUp) {
449
- return false
450
- }
451
- }
452
- // we could do some detection of other touchables and cancel here..
453
- return Math.abs(dy) > 5
454
- }
455
-
456
- const grant = () => {
457
- makeUnselectable(true)
458
- stopSpring()
459
- startY = at.current
460
- }
461
-
462
- let isExternalDrag = false
463
-
464
- scrollBridge.drag = (dy) => {
465
- if (!isExternalDrag) {
466
- isExternalDrag = true
467
- grant()
468
- }
469
- const to = dy + startY
470
- animatedNumber.setValue(resisted(to, minY), { type: 'direct' })
471
- }
472
-
473
- scrollBridge.release = release
474
-
475
- return PanResponder.create({
476
- onMoveShouldSetPanResponder: onMoveShouldSet,
477
- onPanResponderGrant: grant,
478
- onPanResponderMove: (_e, { dy }) => {
479
- const toFull = dy + startY
480
- const to = resisted(toFull, minY)
481
- animatedNumber.setValue(to, { type: 'direct' })
482
- },
483
- onPanResponderEnd: finish,
484
- onPanResponderTerminate: finish,
485
- onPanResponderRelease: finish,
486
- })
487
- },
488
- // eslint-disable-next-line react-hooks/exhaustive-deps
489
- [disableDrag, isShowingInnerSheet, animateTo, frameSize, positions, setPosition]
490
- )
491
-
492
- const animatedStyle = useAnimatedNumberStyle(animatedNumber, (val) => {
493
- 'worklet'
494
- const translateY = frameSize === 0 ? HIDDEN_SIZE : val
495
- return {
496
- transform: [{ translateY }],
497
- }
498
- })
499
-
500
- const sizeBeforeKeyboard = useRef<number | null>(null)
501
- useEffect(() => {
502
- if (isWeb || !moveOnKeyboardChange) return
503
- const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', (e) => {
504
- if (sizeBeforeKeyboard.current !== null) return
505
- sizeBeforeKeyboard.current = animatedNumber.getValue()
506
- animatedNumber.setValue(
507
- Math.max(animatedNumber.getValue() - e.endCoordinates.height, 0)
508
- )
509
- })
510
- const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {
511
- if (sizeBeforeKeyboard.current === null) return
512
- animatedNumber.setValue(sizeBeforeKeyboard.current)
513
- sizeBeforeKeyboard.current = null
514
- })
515
-
516
- return () => {
517
- keyboardDidHideListener.remove()
518
- keyboardDidShowListener.remove()
519
- }
520
- }, [])
521
-
522
- // temp until reanimated useAnimatedNumber fix
523
- const AnimatedView = (driver['NumberView'] ?? driver.View) as typeof Animated.View
524
-
525
- useIsomorphicLayoutEffect(() => {
526
- if (!(parentSheetContext && open)) return
527
- parentSheetContext(true)
528
- return () => {
529
- parentSheetContext(false)
530
- }
531
- }, [parentSheetContext, open])
532
-
533
- const nextParentContext = useMemo(
534
- () => ({
535
- zIndex,
536
- }),
537
- [zIndex]
538
- )
539
-
540
- const handleLayout = useCallback(
541
- (e) => {
542
- let next = e.nativeEvent?.layout.height
543
- if (isWeb && isTouchable && !open) {
544
- // temp fix ios bug where it doesn't go below dynamic bottom...
545
- next += 100
546
- }
547
- if (!next) return
548
- setFrameSize(() => next)
549
- },
550
- [keyboardIsVisible]
551
- )
552
-
553
- const removeScrollEnabled = forceRemoveScrollEnabled ?? (open && modal)
554
-
555
- const contents = (
556
- <ParentSheetContext.Provider value={nextParentContext}>
557
- <SheetProvider {...providerProps}>
558
- {shouldHideParentSheet ? null : overlayComponent}
559
-
560
- <AnimatedView
561
- ref={ref}
562
- {...panResponder?.panHandlers}
563
- onLayout={handleLayout}
564
- pointerEvents={open && !shouldHideParentSheet ? 'auto' : 'none'}
565
- // @ts-ignore
566
- animation={props.animation}
567
- style={[
568
- {
569
- position: 'absolute',
570
- zIndex,
571
- width: '100%',
572
- height: `${maxSnapPoint}%`,
573
- opacity,
574
- },
575
- animatedStyle,
576
- ]}
577
- >
578
- {handleComponent}
579
-
580
- {bottomCoverComponent}
581
- {/* @ts-ignore */}
582
- <RemoveScroll
583
- forwardProps
584
- enabled={removeScrollEnabled}
585
- allowPinchZoom
586
- shards={[contentRef]}
587
- // causes lots of bugs on touch web on site
588
- removeScrollBar={false}
589
- >
590
- {frameComponent}
591
- </RemoveScroll>
592
- </AnimatedView>
593
- </SheetProvider>
594
- </ParentSheetContext.Provider>
595
- )
596
-
597
- const adaptContext = useContext(AdaptParentContext)
598
-
599
- if (modal) {
600
- const modalContents = (
601
- <Portal zIndex={zIndex} {...portalProps}>
602
- <Theme forceClassName name={themeName}>
603
- <AdaptParentContext.Provider value={adaptContext}>
604
- {contents}
605
- </AdaptParentContext.Provider>
606
- </Theme>
607
- </Portal>
608
- )
609
-
610
- if (isWeb) {
611
- return modalContents
612
- }
613
-
614
- // on native we don't support multiple modals yet... fix for now is to hide outer one
615
- return (
616
- <SheetInsideSheetContext.Provider value={onInnerSheet}>
617
- {modalContents}
618
- </SheetInsideSheetContext.Provider>
619
- )
620
- }
621
-
622
- return contents
623
- })
624
- )
625
-
626
- const SheetInsideSheetContext = createContext<((hasChild: boolean) => void) | null>(null)
627
-
628
- export const ControlledSheet = Sheet as FunctionComponent<
629
- Omit<SheetProps, 'open' | 'onOpenChange'> & RefAttributes<View>
630
- > &
631
- typeof sheetComponents
632
-
633
- /* -------------------------------------------------------------------------------------------------*/
117
+ /** @deprecated use Overlay instead */
118
+ export const SheetOverlayFrame = Overlay
634
119
 
635
- function resisted(y: number, minY: number, maxOverflow = 25) {
636
- if (y < minY) {
637
- const past = minY - y
638
- const pctPast = Math.min(maxOverflow, past) / maxOverflow
639
- const diminishBy = 1.1 - Math.pow(0.1, pctPast)
640
- const extra = -diminishBy * maxOverflow
641
- return minY + extra
642
- }
643
- return y
644
- }
120
+ /** @deprecated use Overlay instead */
121
+ export const SheetHandleFrame = Handle
package/src/constants.tsx CHANGED
@@ -2,3 +2,4 @@ export const constants = {}
2
2
 
3
3
  export const SHEET_NAME = 'Sheet'
4
4
  export const SHEET_HANDLE_NAME = 'SheetHandle'
5
+ export const SHEET_OVERLAY_NAME = 'SheetOverlay'