zaman-backoffice 1.0.2 → 1.0.3

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 (114) hide show
  1. package/package.json +1 -1
  2. package/.eslintrc.cjs +0 -26
  3. package/.husky/commit-msg +0 -4
  4. package/.husky/pre-commit +0 -4
  5. package/.idea/git_toolbox_blame.xml +0 -6
  6. package/.idea/git_toolbox_prj.xml +0 -15
  7. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  8. package/.idea/material_theme_project_new.xml +0 -12
  9. package/.idea/modules.xml +0 -8
  10. package/.idea/vcs.xml +0 -6
  11. package/.idea/zaman-backoffice2.iml +0 -12
  12. package/.prettierrc +0 -9
  13. package/.travis.yml +0 -10
  14. package/client/index.html +0 -12
  15. package/client/main.tsx +0 -84
  16. package/client/style.css +0 -62
  17. package/cypress/fixtures/example.json +0 -5
  18. package/cypress/support/commands.ts +0 -38
  19. package/cypress/support/component-index.html +0 -12
  20. package/cypress/support/component.ts +0 -39
  21. package/cypress/videos/Calendar/CalendarComponent.cy.tsx.mp4 +0 -0
  22. package/cypress/videos/DatePicker/DatePicker.cy.tsx.mp4 +0 -0
  23. package/cypress.config.ts +0 -10
  24. package/help/banner.png +0 -0
  25. package/jest.config.ts +0 -47
  26. package/src/components/CalendarItem/CalendarItem.styled.tsx +0 -96
  27. package/src/components/CalendarItem/CalendarItem.types.ts +0 -7
  28. package/src/components/CalendarItem/index.ts +0 -1
  29. package/src/components/CalendarWrapper/CalendarWrapper.styled.tsx +0 -19
  30. package/src/components/CalendarWrapper/index.ts +0 -1
  31. package/src/components/FloatingElement/FloatingElement.styled.tsx +0 -8
  32. package/src/components/FloatingElement/FloatingElement.tsx +0 -83
  33. package/src/components/FloatingElement/FloatingElement.types.ts +0 -8
  34. package/src/components/FloatingElement/index.tsx +0 -1
  35. package/src/components/Header/Header.styled.tsx +0 -40
  36. package/src/components/Header/Header.tsx +0 -46
  37. package/src/components/Header/Header.types.ts +0 -6
  38. package/src/components/Header/index.ts +0 -1
  39. package/src/components/IconButton/IconButton.styled.tsx +0 -22
  40. package/src/components/IconButton/IconButton.tsx +0 -3
  41. package/src/components/IconButton/index.tsx +0 -1
  42. package/src/components/Icons/ChevronLeft/index.tsx +0 -22
  43. package/src/components/Icons/ChevronRight/index.tsx +0 -22
  44. package/src/components/Modal/Modal.styled.tsx +0 -23
  45. package/src/components/Modal/Modal.tsx +0 -29
  46. package/src/components/Modal/index.tsx +0 -1
  47. package/src/components/Modal/types.ts +0 -7
  48. package/src/components/MonthPicker/Month.styled.tsx +0 -11
  49. package/src/components/MonthPicker/MonthPicker.tsx +0 -35
  50. package/src/components/MonthPicker/MonthPicker.types.ts +0 -4
  51. package/src/components/MonthPicker/index.ts +0 -1
  52. package/src/components/RenderCalendar/RenderCalendar.tsx +0 -31
  53. package/src/components/RenderCalendar/RenderCalendar.types.ts +0 -10
  54. package/src/components/RenderCalendar/index.ts +0 -1
  55. package/src/components/YearPicker/YearPicker.styled.tsx +0 -14
  56. package/src/components/YearPicker/YearPicker.tsx +0 -49
  57. package/src/components/YearPicker/YearPicker.types.ts +0 -4
  58. package/src/components/YearPicker/index.ts +0 -1
  59. package/src/constants.ts +0 -6
  60. package/src/hooks/__tests__/useClickOutside.test.tsx +0 -32
  61. package/src/hooks/useCalendarHandlers.tsx +0 -113
  62. package/src/hooks/useClickOutside.tsx +0 -23
  63. package/src/hooks/useSlideCalendar.tsx +0 -95
  64. package/src/hooks/useTimePicker.tsx +0 -95
  65. package/src/index.tsx +0 -4
  66. package/src/packages/Calendar/Calendar.styled.tsx +0 -42
  67. package/src/packages/Calendar/Calendar.tsx +0 -159
  68. package/src/packages/Calendar/Calendar.types.ts +0 -31
  69. package/src/packages/Calendar/CalendarComponent.cy.tsx +0 -69
  70. package/src/packages/Calendar/index.ts +0 -2
  71. package/src/packages/CalendarProvider/CalendarProvider.tsx +0 -30
  72. package/src/packages/CalendarProvider/CalendarProvider.types.ts +0 -6
  73. package/src/packages/CalendarProvider/index.ts +0 -2
  74. package/src/packages/DatePicker/DatePicker.cy.tsx +0 -54
  75. package/src/packages/DatePicker/DatePicker.tsx +0 -127
  76. package/src/packages/DatePicker/DatePicker.types.ts +0 -26
  77. package/src/packages/DatePicker/index.ts +0 -2
  78. package/src/packages/TimePicker/TimePicker.styled.tsx +0 -77
  79. package/src/packages/TimePicker/TimePicker.tsx +0 -121
  80. package/src/packages/TimePicker/TimePicker.types.ts +0 -16
  81. package/src/packages/TimePicker/components/Numbers/Numbers.styled.tsx +0 -36
  82. package/src/packages/TimePicker/components/Numbers/Numbers.tsx +0 -58
  83. package/src/packages/TimePicker/components/Numbers/Numbers.types.ts +0 -14
  84. package/src/packages/TimePicker/components/Numbers/index.ts +0 -1
  85. package/src/packages/TimePicker/index.ts +0 -2
  86. package/src/style/animation.ts +0 -23
  87. package/src/style/classNames.ts +0 -8
  88. package/src/style/colorPallete.ts +0 -16
  89. package/src/style/colors.ts +0 -15
  90. package/src/style/hexToHSL.ts +0 -52
  91. package/src/style/radius.ts +0 -28
  92. package/src/types.ts +0 -75
  93. package/src/utils/dateHelper/dateHelper.ts +0 -67
  94. package/src/utils/dateHelper/index.ts +0 -1
  95. package/src/utils/dateTimeFormat/dateTimeFormat.ts +0 -43
  96. package/src/utils/dateTimeFormat/index.ts +0 -1
  97. package/src/utils/format/format.test.ts +0 -37
  98. package/src/utils/format/format.ts +0 -56
  99. package/src/utils/format/format.types.ts +0 -11
  100. package/src/utils/format/index.ts +0 -1
  101. package/src/utils/index.ts +0 -21
  102. package/src/utils/locale.ts +0 -13
  103. package/src/utils/locales/en.ts +0 -89
  104. package/src/utils/locales/fa.ts +0 -89
  105. package/src/utils/locales/index.ts +0 -10
  106. package/src/utils/locales/locales.types.ts +0 -11
  107. package/src/utils/month/index.ts +0 -1
  108. package/src/utils/month/month.ts +0 -54
  109. package/src/utils/month/month.types.ts +0 -11
  110. package/src/utils/timePicker.ts +0 -107
  111. package/src/utils/type.ts +0 -0
  112. package/tsconfig.json +0 -22
  113. package/tsconfig.test.json +0 -7
  114. package/vite.config.ts +0 -7
@@ -1,83 +0,0 @@
1
- import React, { useEffect, useRef } from 'react'
2
- import { createPortal } from 'react-dom'
3
- import debounce from 'lodash.debounce'
4
- import type { FloatingElementProps } from './FloatingElement.types'
5
- import type { Positions } from '../../types'
6
- import { Wrapper } from './FloatingElement.styled'
7
-
8
- const FloatingElement: React.FC<FloatingElementProps> = (props) => {
9
- const { children, destinationRef, position } = props
10
- const floatWrapperRef = useRef<HTMLDivElement>(null)
11
-
12
- const calcPlacement = () => {
13
- const gap = 4
14
- let top = 0
15
-
16
- if (destinationRef != null && floatWrapperRef !== null) {
17
- const floatWrapper = floatWrapperRef.current
18
- if (floatWrapper === null) {
19
- return
20
- }
21
- const {
22
- top: destTop,
23
- bottom: destBottom,
24
- right: destRight,
25
- left: destLeft,
26
- width: destWidth
27
- } = destinationRef?.current?.getBoundingClientRect() as DOMRect
28
- const { height: itemsHeight, width: floatWidth } =
29
- floatWrapper?.getBoundingClientRect()
30
- const isThereSpaceBelowDest =
31
- window.innerHeight - destBottom > itemsHeight
32
-
33
- if (isThereSpaceBelowDest) {
34
- top = destBottom + window.scrollY
35
- } else {
36
- top = destTop + window.scrollY - itemsHeight - gap * 2
37
- }
38
- floatWrapper.style.top = `${top + gap}px`
39
-
40
- const positionsCalc: Record<Positions, () => void> = {
41
- right: () => {
42
- floatWrapper.style.right = `${
43
- Math.abs(document.body.clientWidth - destRight) + 16
44
- }px`
45
- },
46
- left: () => {
47
- floatWrapper.style.left = `${destLeft}px`
48
- },
49
- center: () => {
50
- const isDestBiggerThanFloatElement = floatWidth > destWidth
51
- const remainWidth = isDestBiggerThanFloatElement
52
- ? 0
53
- : Math.abs(floatWidth - destWidth) / 2 + 16
54
- floatWrapper.style.right = `${
55
- Math.abs(document.body.clientWidth - destRight) + remainWidth
56
- }px`
57
- }
58
- }
59
-
60
- positionsCalc[position]()
61
- }
62
- }
63
-
64
- useEffect(() => {
65
- calcPlacement()
66
- window.addEventListener('resize', debounce(calcPlacement, 500))
67
-
68
- return () => {
69
- window.removeEventListener('resize', calcPlacement)
70
- }
71
- }, [destinationRef])
72
-
73
- return (
74
- <>
75
- {createPortal(
76
- <Wrapper ref={floatWrapperRef}>{children}</Wrapper>,
77
- document.body
78
- )}
79
- </>
80
- )
81
- }
82
-
83
- export default FloatingElement
@@ -1,8 +0,0 @@
1
- import type React from 'react'
2
- import type { Positions } from '../../types'
3
-
4
- export interface FloatingElementProps {
5
- children: React.ReactNode
6
- destinationRef: React.RefObject<HTMLInputElement>
7
- position: Positions
8
- }
@@ -1 +0,0 @@
1
- export { default } from './FloatingElement'
@@ -1,40 +0,0 @@
1
- import styled from '@emotion/styled'
2
- import { radius } from '../../style/radius'
3
-
4
- export const Wrapper = styled.div`
5
- display: flex;
6
- justify-content: space-between;
7
- align-items: center;
8
- height: 56px;
9
- padding-right: 8px;
10
- padding-left: 8px;
11
- background-color: ${(props) => props.theme.colors.primary[95]};
12
- border-bottom: 2px solid ${(props) => props.theme.colors.primary[85]};
13
- `
14
- export const HeaderTitle = styled.button`
15
- will-change: auto;
16
- min-width: 100px;
17
- outline: none;
18
- border: 0;
19
- font-family: inherit;
20
- background-color: transparent;
21
- cursor: pointer;
22
- color: ${(props) => props.theme.colors.primary[50]};
23
- padding: 8px 16px;
24
- font-weight: 500;
25
- transition: background-color 0.2s ease-in;
26
- border-radius: ${(props) => radius[props.theme.round].calendarItem}px;
27
-
28
- &:hover,
29
- &:focus {
30
- background-color: ${(props) => props.theme.colors.primary[90]};
31
- }
32
- `
33
- export const DayName = styled.div`
34
- display: flex;
35
- justify-content: center;
36
- align-items: center;
37
- font-size: 14px;
38
- width: 40px;
39
- color: #8c8c8c;
40
- `
@@ -1,46 +0,0 @@
1
- import React from 'react'
2
- import IconButton from '../IconButton'
3
- import ChevronRight from '../Icons/ChevronRight'
4
- import ChevronLeft from '../Icons/ChevronLeft'
5
- import { Wrapper, HeaderTitle } from './Header.styled'
6
- import type { HeaderProps } from './Header.types'
7
- import {
8
- HeaderClass,
9
- IconNextButton,
10
- IconPrevButton,
11
- MonthYearButton
12
- } from '../../style/classNames'
13
-
14
- export const Header = (props: HeaderProps) => {
15
- return (
16
- <Wrapper className={HeaderClass}>
17
- <IconButton
18
- aria-label="Previous month"
19
- onClick={props.onPrevClick}
20
- className={IconPrevButton}
21
- tabIndex={0}
22
- >
23
- <ChevronRight />
24
- </IconButton>
25
- <HeaderTitle
26
- className={MonthYearButton}
27
- role="presentation"
28
- onClick={props.onClickOnTitle}
29
- aria-label="calendar view is open, switch to year and month view"
30
- tabIndex={0}
31
- >
32
- {props.monthName}
33
- </HeaderTitle>
34
- <IconButton
35
- aria-label="Next month"
36
- onClick={props.onNextClick}
37
- className={IconNextButton}
38
- tabIndex={0}
39
- >
40
- <ChevronLeft />
41
- </IconButton>
42
- </Wrapper>
43
- )
44
- }
45
-
46
- export default Header
@@ -1,6 +0,0 @@
1
- export interface HeaderProps {
2
- monthName: string
3
- onNextClick: () => void
4
- onPrevClick: () => void
5
- onClickOnTitle: () => void
6
- }
@@ -1 +0,0 @@
1
- export { default } from './Header'
@@ -1,22 +0,0 @@
1
- import styled from '@emotion/styled'
2
- import { radius } from '../../style/radius'
3
-
4
- export const IconButton = styled.button`
5
- cursor: pointer;
6
- outline: none;
7
- border: none;
8
- display: flex;
9
- justify-content: center;
10
- align-items: center;
11
- width: 40px;
12
- height: 40px;
13
- transition: background-color 0.2s ease-in;
14
- color: ${(props) => props.theme.colors.primary[50]};
15
- background-color: transparent;
16
- border-radius: ${(props) => radius[props.theme.round].calendarItem}px;
17
-
18
- &:hover,
19
- &:focus {
20
- background-color: ${(props) => props.theme.colors.primary[90]};
21
- }
22
- `
@@ -1,3 +0,0 @@
1
- import { IconButton } from './IconButton.styled'
2
-
3
- export default IconButton
@@ -1 +0,0 @@
1
- export { default } from './IconButton'
@@ -1,22 +0,0 @@
1
- import React from 'react'
2
- import { isRtl } from '../../../utils'
3
-
4
- export const ChevronLeft = () => (
5
- <svg
6
- xmlns="http://www.w3.org/2000/svg"
7
- width="20"
8
- height="20"
9
- viewBox="0 0 24 24"
10
- fill="none"
11
- stroke="currentColor"
12
- strokeWidth="2"
13
- strokeLinecap="round"
14
- strokeLinejoin="round"
15
- className="feather feather-chevron-left"
16
- style={{ transform: isRtl() ? 'unset' : 'rotate(180deg)' }}
17
- >
18
- <polyline points="15 18 9 12 15 6"></polyline>
19
- </svg>
20
- )
21
-
22
- export default ChevronLeft
@@ -1,22 +0,0 @@
1
- import React from 'react'
2
- import { isRtl } from '../../../utils'
3
-
4
- export const ChevronRight = () => (
5
- <svg
6
- xmlns="http://www.w3.org/2000/svg"
7
- width="20"
8
- height="20"
9
- viewBox="0 0 24 24"
10
- fill="none"
11
- stroke="currentColor"
12
- strokeWidth="2"
13
- strokeLinecap="round"
14
- strokeLinejoin="round"
15
- className="feather feather-chevron-right"
16
- style={{ transform: isRtl() ? 'unset' : 'rotate(180deg)' }}
17
- >
18
- <polyline points="9 18 15 12 9 6"></polyline>
19
- </svg>
20
- )
21
-
22
- export default ChevronRight
@@ -1,23 +0,0 @@
1
- import styled from '@emotion/styled'
2
-
3
- export const ModalDiv = styled.div`
4
- position: fixed;
5
- display: flex;
6
- justify-content: center;
7
- align-items: center;
8
- top: 0;
9
- right: 0;
10
- width: 100%;
11
- height: 100%;
12
- z-index: 10;
13
-
14
- .rdp__overlay {
15
- position: absolute;
16
- top: 0;
17
- right: 0;
18
- width: 100%;
19
- height: 100%;
20
- z-index: -10;
21
- background-color: rgba(86, 86, 86, 0.4);
22
- }
23
- `
@@ -1,29 +0,0 @@
1
- import React from 'react'
2
- import type { IModalProps } from './types'
3
- import { ModalDiv } from './Modal.styled'
4
- import { createPortal } from 'react-dom'
5
-
6
- export const Modal = (props: IModalProps) => {
7
- const { open, toggleOpen, children } = props
8
-
9
- if (open === false) {
10
- return null
11
- }
12
- return (
13
- <>
14
- {createPortal(
15
- <ModalDiv className="rdp__modal">
16
- {children}
17
- <div
18
- data-testid="overlay"
19
- className="rdp__overlay"
20
- onClick={toggleOpen}
21
- />
22
- </ModalDiv>,
23
- document.body
24
- )}
25
- </>
26
- )
27
- }
28
-
29
- export default Modal
@@ -1 +0,0 @@
1
- export { default } from './Modal'
@@ -1,7 +0,0 @@
1
- import type * as React from 'react'
2
-
3
- export interface IModalProps {
4
- open?: boolean
5
- children: React.ReactNode
6
- toggleOpen: () => void
7
- }
@@ -1,11 +0,0 @@
1
- import styled from '@emotion/styled'
2
- import { CALENDAR_WIDTH } from '../../constants'
3
-
4
- export const Wrapper = styled.div`
5
- display: flex;
6
- justify-content: center;
7
- align-items: center;
8
- flex-wrap: wrap;
9
- gap: 4px;
10
- height: ${CALENDAR_WIDTH}px;
11
- `
@@ -1,35 +0,0 @@
1
- import React from 'react'
2
- import localeCache from '../../utils/locale'
3
- import locales from '../../utils/locales'
4
- import CalendarItem from '../CalendarItem'
5
- import { Wrapper } from './Month.styled'
6
- import formatDate from '../../utils/format'
7
- import type { MonthPickerProps } from './MonthPicker.types'
8
- import { MonthPickerButton } from '../../style/classNames'
9
-
10
- export const MonthPicker = (props: MonthPickerProps) => {
11
- const { locale } = localeCache
12
- const currentMonth = formatDate(props.value, 'MM', 'latn')
13
-
14
- return (
15
- <Wrapper>
16
- {locales[locale].months.map((month) => (
17
- <CalendarItem
18
- key={month.key}
19
- className={MonthPickerButton}
20
- width={90}
21
- height={48}
22
- data-selected={month.key === parseInt(currentMonth, 10)}
23
- onClick={() => props.onMonthSelect(month.key)}
24
- aria-current="date"
25
- type="button"
26
- tabIndex={0}
27
- >
28
- {month.name}
29
- </CalendarItem>
30
- ))}
31
- </Wrapper>
32
- )
33
- }
34
-
35
- export default MonthPicker
@@ -1,4 +0,0 @@
1
- export interface MonthPickerProps {
2
- value: Date
3
- onMonthSelect: (month: number) => void
4
- }
@@ -1 +0,0 @@
1
- export { default } from './MonthPicker'
@@ -1,31 +0,0 @@
1
- import React from 'react'
2
- import { type RenderCalendarProps } from './RenderCalendar.types'
3
- import FloatingElement from '../FloatingElement'
4
- import Modal from '../Modal'
5
-
6
- export const RenderCalendar = (props: RenderCalendarProps) => {
7
- const { position = 'right' } = props
8
- if (!props.showCalendar) {
9
- return null
10
- }
11
- const { matches: isDesktop } = window.matchMedia('(min-width: 640px)')
12
-
13
- if (isDesktop) {
14
- return (
15
- <FloatingElement
16
- destinationRef={props.destinationRef}
17
- position={position}
18
- >
19
- {props.children}
20
- </FloatingElement>
21
- )
22
- }
23
-
24
- return (
25
- <Modal toggleOpen={props.toggleOpen} open={props.showCalendar}>
26
- {props.children}
27
- </Modal>
28
- )
29
- }
30
-
31
- export default RenderCalendar
@@ -1,10 +0,0 @@
1
- import type React from 'react'
2
- import type { Positions } from '../../types'
3
-
4
- export interface RenderCalendarProps {
5
- showCalendar: boolean
6
- toggleOpen: () => void
7
- children: React.ReactNode
8
- destinationRef: React.RefObject<HTMLInputElement>
9
- position?: Positions
10
- }
@@ -1 +0,0 @@
1
- export { default } from './RenderCalendar'
@@ -1,14 +0,0 @@
1
- import styled from '@emotion/styled'
2
- import { CALENDAR_WIDTH } from '../../constants'
3
-
4
- export const Wrapper = styled.div`
5
- display: grid;
6
- grid-template-columns: repeat(3, 92px);
7
- grid-template-rows: auto;
8
- justify-content: center;
9
- gap: 4px;
10
- max-height: ${CALENDAR_WIDTH}px;
11
- overflow: auto;
12
- padding-top: 8px;
13
- padding-bottom: 8px;
14
- `
@@ -1,49 +0,0 @@
1
- import React, { useMemo } from 'react'
2
- import CalendarItem from '../CalendarItem'
3
- import { Wrapper } from './YearPicker.styled'
4
- import { getYears } from '../../utils/dateHelper/dateHelper'
5
- import formatDate from '../../utils/format'
6
- import type { YearPickerProps } from './YearPicker.types'
7
- import { localizeNumber } from '../../utils'
8
- import { YearPickerButton } from '../../style/classNames'
9
-
10
- export const YearPicker = (props: YearPickerProps) => {
11
- const currentYear = parseInt(formatDate(props.value, 'YYYY', 'latn'), 10)
12
- const years: number[] = useMemo(() => getYears(props.value), [])
13
-
14
- const wrapperRef = React.useCallback((wrapper: HTMLDivElement) => {
15
- if (wrapper === null) {
16
- return
17
- }
18
- const qu = wrapper.querySelector('button[data-selected=true]')
19
- if (qu != null) {
20
- const { height: wrapperHeight, top: wrapperTop } =
21
- wrapper.getBoundingClientRect()
22
- const { top } = qu.getBoundingClientRect()
23
- wrapper.scrollTop = Math.abs(wrapperTop - top) - wrapperHeight / 2
24
- }
25
- }, [])
26
-
27
- return (
28
- <Wrapper ref={wrapperRef}>
29
- {years.map((year) => (
30
- <CalendarItem
31
- className={YearPickerButton}
32
- key={year}
33
- width={90}
34
- height={48}
35
- data-selected={currentYear === year}
36
- aria-selected={currentYear === year}
37
- aria-current="date"
38
- type="button"
39
- tabIndex={0}
40
- onClick={() => props.onYearSelect(year)}
41
- >
42
- {localizeNumber(year)}
43
- </CalendarItem>
44
- ))}
45
- </Wrapper>
46
- )
47
- }
48
-
49
- export default YearPicker
@@ -1,4 +0,0 @@
1
- export interface YearPickerProps {
2
- value: Date
3
- onYearSelect: (year: number) => void
4
- }
@@ -1 +0,0 @@
1
- export { default } from './YearPicker'
package/src/constants.ts DELETED
@@ -1,6 +0,0 @@
1
- export const TIME = 250
2
- export const CALENDAR_WIDTH = 320
3
- export const CALENDAR_HEIGHT = 372
4
- export const ANIMATE_FUNC = 'cubic-bezier(0.4, 0, 0.2, 1)'
5
-
6
- export const ACCENT_COLOR = '#0D59F2'
@@ -1,32 +0,0 @@
1
- import React, { useRef } from 'react'
2
- import useClickOutside from '../useClickOutside'
3
- import { fireEvent, render, screen } from '@testing-library/react'
4
-
5
- interface MockComponentProps {
6
- handler: () => void
7
- }
8
- const MockComponent = (props: MockComponentProps) => {
9
- const insideRef = useRef(null)
10
- useClickOutside(insideRef, props.handler)
11
- return (
12
- <div>
13
- <div>click outside</div>
14
- <div ref={insideRef}>Click inside</div>
15
- </div>
16
- )
17
- }
18
- test('test click on inside', () => {
19
- const mockCallback = jest.fn(() => {})
20
- render(<MockComponent handler={mockCallback} />)
21
- fireEvent.mouseDown(screen.getByText(/click inside/i))
22
-
23
- expect(mockCallback.mock.calls.length).toBe(0)
24
- })
25
-
26
- test('test click on outside', () => {
27
- const mockCallback = jest.fn(() => {})
28
- render(<MockComponent handler={mockCallback} />)
29
- fireEvent.mouseDown(screen.getByText(/click outside/i))
30
-
31
- expect(mockCallback.mock.calls.length).toBe(1)
32
- })
@@ -1,113 +0,0 @@
1
- import { type SyntheticEvent, useState } from 'react'
2
- import dayjs from 'dayjs'
3
- import type { DatePickerValue } from '../types'
4
- import type {
5
- CalendarDefaultProps,
6
- CalendarRangeProps
7
- } from 'src/packages/Calendar/Calendar.types'
8
-
9
- type Event = SyntheticEvent<HTMLButtonElement>
10
-
11
- interface BaseUseCalendarHandlersType {
12
- from?: DatePickerValue
13
- to?: DatePickerValue
14
- }
15
-
16
- type useCalendarHandlersType = BaseUseCalendarHandlersType &
17
- (CalendarRangeProps | CalendarDefaultProps)
18
-
19
- export const guardRange = (
20
- value: useCalendarHandlersType
21
- ): value is CalendarRangeProps => {
22
- return value.range === true
23
- }
24
-
25
- export const useCalendarHandlers = (props: useCalendarHandlersType) => {
26
- const [selectingRange, setSelectingRange] = useState(false)
27
- const [from, setFrom] = useState<Date | undefined>(
28
- props.from !== undefined ? new Date(props.from) : undefined
29
- )
30
- const [to, setTo] = useState<Date | undefined | null>(
31
- props.to !== undefined ? new Date(props.to) : undefined
32
- )
33
-
34
- const onClickCalendar = (e: Event) => {
35
- const { value, disabled } = e.currentTarget.dataset
36
- if (value === undefined) {
37
- return
38
- }
39
- if (disabled === 'true') {
40
- return
41
- }
42
-
43
- if (!guardRange(props) && typeof props.onChange === 'function') {
44
- props.onChange({ value: new Date(value) })
45
- }
46
-
47
- return value
48
- }
49
- const onClickRange = (e: Event) => {
50
- const { value } = e.currentTarget.dataset
51
- // start selecting range
52
- if (!selectingRange) {
53
- if (value !== undefined) {
54
- setFrom(new Date(value))
55
- setTo(null)
56
- }
57
- setSelectingRange(true)
58
- }
59
- // submit select date in mobile
60
- if (selectingRange && to === null) {
61
- if (value !== undefined) {
62
- setTo(new Date(value))
63
- handleRangeOnChange(from, new Date(value))
64
- }
65
- setSelectingRange(false)
66
- }
67
- // finish selecting range in desktop
68
- if (selectingRange && to !== undefined) {
69
- handleRangeOnChange(from, to)
70
- setSelectingRange(false)
71
- }
72
- }
73
- const onMouseMove = (e: Event) => {
74
- const { value } = e.currentTarget.dataset
75
- if (!selectingRange) {
76
- return
77
- }
78
- if (value !== undefined) {
79
- if (dayjs(value).isAfter(dayjs(from))) {
80
- setTo(new Date(value))
81
- }
82
- }
83
- }
84
- const handleClickEvent = (e: Event) => {
85
- if (props.range === true) {
86
- return onClickRange(e)
87
- }
88
- return onClickCalendar(e)
89
- }
90
- const handleRangeOnChange = (
91
- from: Date | undefined,
92
- to: Date | undefined | null
93
- ) => {
94
- if (typeof props.onChange === 'function' && guardRange(props)) {
95
- if (from != null && to != null) {
96
- props.onChange({
97
- from,
98
- to
99
- })
100
- }
101
- }
102
- }
103
- return {
104
- handlers: {
105
- onClick: handleClickEvent,
106
- ...(props.range === true && { onMouseMove })
107
- },
108
- from,
109
- to
110
- }
111
- }
112
-
113
- export default useCalendarHandlers