@coreui/react-pro 5.25.0 → 5.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/dist/cjs/components/card/CCardImage.js.map +1 -1
- package/dist/cjs/components/carousel/CCarousel.js +44 -33
- package/dist/cjs/components/carousel/CCarousel.js.map +1 -1
- package/dist/cjs/components/carousel/CCarouselItem.js +19 -28
- package/dist/cjs/components/carousel/CCarouselItem.js.map +1 -1
- package/dist/cjs/components/chip/CChip.d.ts +12 -0
- package/dist/cjs/components/chip/CChip.js +16 -63
- package/dist/cjs/components/chip/CChip.js.map +1 -1
- package/dist/cjs/components/chip/const.d.ts +1 -0
- package/dist/cjs/components/chip/const.js +8 -0
- package/dist/cjs/components/chip/const.js.map +1 -0
- package/dist/cjs/components/chip-set/CChipSet.d.ts +73 -0
- package/dist/cjs/components/chip-set/CChipSet.js +66 -0
- package/dist/cjs/components/chip-set/CChipSet.js.map +1 -0
- package/dist/cjs/components/chip-set/index.d.ts +2 -0
- package/dist/cjs/components/chip-set/useChipSet.d.ts +48 -0
- package/dist/cjs/components/chip-set/useChipSet.js +163 -0
- package/dist/cjs/components/chip-set/useChipSet.js.map +1 -0
- package/dist/cjs/components/chip-set/utils.d.ts +7 -0
- package/dist/cjs/components/chip-set/utils.js +18 -0
- package/dist/cjs/components/chip-set/utils.js.map +1 -0
- package/dist/cjs/components/collapse/CCollapse.js +14 -6
- package/dist/cjs/components/collapse/CCollapse.js.map +1 -1
- package/dist/cjs/components/conditional-portal/CConditionalPortal.js +3 -1
- package/dist/cjs/components/conditional-portal/CConditionalPortal.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdown.js +22 -29
- package/dist/cjs/components/dropdown/CDropdown.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdownToggle.js.map +1 -1
- package/dist/cjs/components/form/CChipInput.d.ts +14 -2
- package/dist/cjs/components/form/CChipInput.js +77 -49
- package/dist/cjs/components/form/CChipInput.js.map +1 -1
- package/dist/cjs/components/form/CFormCheck.js.map +1 -1
- package/dist/cjs/components/form/CFormInput.js.map +1 -1
- package/dist/cjs/components/form/CFormSelect.js.map +1 -1
- package/dist/cjs/components/form/CFormTextarea.js.map +1 -1
- package/dist/cjs/components/form/CInputGroupText.js.map +1 -1
- package/dist/cjs/components/grid/CContainer.js +3 -1
- package/dist/cjs/components/grid/CContainer.js.map +1 -1
- package/dist/cjs/components/header/CHeaderBrand.js.map +1 -1
- package/dist/cjs/components/index.d.ts +1 -0
- package/dist/cjs/components/link/CLink.js +4 -2
- package/dist/cjs/components/link/CLink.js.map +1 -1
- package/dist/cjs/components/list-group/CListGroupItem.js.map +1 -1
- package/dist/cjs/components/modal/CModal.js +14 -2
- package/dist/cjs/components/modal/CModal.js.map +1 -1
- package/dist/cjs/components/multi-select/CMultiSelect.d.ts +73 -1
- package/dist/cjs/components/multi-select/CMultiSelect.js +157 -18
- package/dist/cjs/components/multi-select/CMultiSelect.js.map +1 -1
- package/dist/cjs/components/multi-select/CMultiSelectNativeSelect.js +1 -1
- package/dist/cjs/components/multi-select/CMultiSelectNativeSelect.js.map +1 -1
- package/dist/cjs/components/multi-select/CMultiSelectOptions.d.ts +3 -0
- package/dist/cjs/components/multi-select/CMultiSelectOptions.js +45 -2
- package/dist/cjs/components/multi-select/CMultiSelectOptions.js.map +1 -1
- package/dist/cjs/components/multi-select/CMultiSelectSelection.d.ts +1 -0
- package/dist/cjs/components/multi-select/CMultiSelectSelection.js +4 -3
- package/dist/cjs/components/multi-select/CMultiSelectSelection.js.map +1 -1
- package/dist/cjs/components/multi-select/types.d.ts +12 -0
- package/dist/cjs/components/multi-select/utils.js +1 -4
- package/dist/cjs/components/multi-select/utils.js.map +1 -1
- package/dist/cjs/components/nav/CNav.js.map +1 -1
- package/dist/cjs/components/nav/CNavGroup.d.ts +10 -5
- package/dist/cjs/components/nav/CNavGroup.js +83 -24
- package/dist/cjs/components/nav/CNavGroup.js.map +1 -1
- package/dist/cjs/components/nav/CNavGroupContext.d.ts +25 -0
- package/dist/cjs/components/nav/CNavGroupContext.js +13 -0
- package/dist/cjs/components/nav/CNavGroupContext.js.map +1 -0
- package/dist/cjs/components/nav/CNavLink.d.ts +1 -5
- package/dist/cjs/components/nav/CNavLink.js +21 -8
- package/dist/cjs/components/nav/CNavLink.js.map +1 -1
- package/dist/cjs/components/popover/CPopover.js +57 -9
- package/dist/cjs/components/popover/CPopover.js.map +1 -1
- package/dist/cjs/components/progress/CProgress.js.map +1 -1
- package/dist/cjs/components/rating/CRating.d.ts +1 -1
- package/dist/cjs/components/rating/CRating.js.map +1 -1
- package/dist/cjs/components/sidebar/CSidebar.js +40 -23
- package/dist/cjs/components/sidebar/CSidebar.js.map +1 -1
- package/dist/cjs/components/sidebar/CSidebarNav.js +6 -35
- package/dist/cjs/components/sidebar/CSidebarNav.js.map +1 -1
- package/dist/cjs/components/table/CTableDataCell.js.map +1 -1
- package/dist/cjs/components/table/types.d.ts +2 -1
- package/dist/cjs/components/table/utils.js +4 -4
- package/dist/cjs/components/table/utils.js.map +1 -1
- package/dist/cjs/components/tabs/CTabPanel.js +3 -1
- package/dist/cjs/components/tabs/CTabPanel.js.map +1 -1
- package/dist/cjs/components/tooltip/CTooltip.js +57 -9
- package/dist/cjs/components/tooltip/CTooltip.js.map +1 -1
- package/dist/cjs/helpers/polymorphicComponent.d.ts +1 -2
- package/dist/cjs/hooks/useForkedRef.d.ts +1 -1
- package/dist/cjs/hooks/useForkedRef.js +6 -3
- package/dist/cjs/hooks/useForkedRef.js.map +1 -1
- package/dist/cjs/hooks/usePopper.js +8 -6
- package/dist/cjs/hooks/usePopper.js.map +1 -1
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +1 -1
- package/dist/cjs/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js.map +1 -1
- package/dist/cjs/node_modules/ua-parser-js/dist/ua-parser.min.js +3 -3
- package/dist/cjs/node_modules/ua-parser-js/dist/ua-parser.min.js.map +1 -1
- package/dist/cjs/utils/executeAfterTransition.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +2 -1
- package/dist/cjs/utils/swipe.d.ts +26 -0
- package/dist/cjs/utils/swipe.js +94 -0
- package/dist/cjs/utils/swipe.js.map +1 -0
- package/dist/esm/components/card/CCardImage.js.map +1 -1
- package/dist/esm/components/carousel/CCarousel.js +44 -33
- package/dist/esm/components/carousel/CCarousel.js.map +1 -1
- package/dist/esm/components/carousel/CCarouselItem.js +19 -28
- package/dist/esm/components/carousel/CCarouselItem.js.map +1 -1
- package/dist/esm/components/chip/CChip.d.ts +12 -0
- package/dist/esm/components/chip/CChip.js +16 -63
- package/dist/esm/components/chip/CChip.js.map +1 -1
- package/dist/esm/components/chip/const.d.ts +1 -0
- package/dist/esm/components/chip/const.js +6 -0
- package/dist/esm/components/chip/const.js.map +1 -0
- package/dist/esm/components/chip-set/CChipSet.d.ts +73 -0
- package/dist/esm/components/chip-set/CChipSet.js +64 -0
- package/dist/esm/components/chip-set/CChipSet.js.map +1 -0
- package/dist/esm/components/chip-set/index.d.ts +2 -0
- package/dist/esm/components/chip-set/useChipSet.d.ts +48 -0
- package/dist/esm/components/chip-set/useChipSet.js +161 -0
- package/dist/esm/components/chip-set/useChipSet.js.map +1 -0
- package/dist/esm/components/chip-set/utils.d.ts +7 -0
- package/dist/esm/components/chip-set/utils.js +16 -0
- package/dist/esm/components/chip-set/utils.js.map +1 -0
- package/dist/esm/components/collapse/CCollapse.js +14 -6
- package/dist/esm/components/collapse/CCollapse.js.map +1 -1
- package/dist/esm/components/conditional-portal/CConditionalPortal.js +3 -1
- package/dist/esm/components/conditional-portal/CConditionalPortal.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdown.js +22 -29
- package/dist/esm/components/dropdown/CDropdown.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdownToggle.js.map +1 -1
- package/dist/esm/components/form/CChipInput.d.ts +14 -2
- package/dist/esm/components/form/CChipInput.js +78 -50
- package/dist/esm/components/form/CChipInput.js.map +1 -1
- package/dist/esm/components/form/CFormCheck.js.map +1 -1
- package/dist/esm/components/form/CFormInput.js.map +1 -1
- package/dist/esm/components/form/CFormSelect.js.map +1 -1
- package/dist/esm/components/form/CFormTextarea.js.map +1 -1
- package/dist/esm/components/form/CInputGroupText.js.map +1 -1
- package/dist/esm/components/grid/CContainer.js +3 -1
- package/dist/esm/components/grid/CContainer.js.map +1 -1
- package/dist/esm/components/header/CHeaderBrand.js.map +1 -1
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/link/CLink.js +4 -2
- package/dist/esm/components/link/CLink.js.map +1 -1
- package/dist/esm/components/list-group/CListGroupItem.js.map +1 -1
- package/dist/esm/components/modal/CModal.js +14 -2
- package/dist/esm/components/modal/CModal.js.map +1 -1
- package/dist/esm/components/multi-select/CMultiSelect.d.ts +73 -1
- package/dist/esm/components/multi-select/CMultiSelect.js +158 -19
- package/dist/esm/components/multi-select/CMultiSelect.js.map +1 -1
- package/dist/esm/components/multi-select/CMultiSelectNativeSelect.js +1 -1
- package/dist/esm/components/multi-select/CMultiSelectNativeSelect.js.map +1 -1
- package/dist/esm/components/multi-select/CMultiSelectOptions.d.ts +3 -0
- package/dist/esm/components/multi-select/CMultiSelectOptions.js +45 -2
- package/dist/esm/components/multi-select/CMultiSelectOptions.js.map +1 -1
- package/dist/esm/components/multi-select/CMultiSelectSelection.d.ts +1 -0
- package/dist/esm/components/multi-select/CMultiSelectSelection.js +4 -3
- package/dist/esm/components/multi-select/CMultiSelectSelection.js.map +1 -1
- package/dist/esm/components/multi-select/types.d.ts +12 -0
- package/dist/esm/components/multi-select/utils.js +1 -4
- package/dist/esm/components/multi-select/utils.js.map +1 -1
- package/dist/esm/components/nav/CNav.js.map +1 -1
- package/dist/esm/components/nav/CNavGroup.d.ts +10 -5
- package/dist/esm/components/nav/CNavGroup.js +84 -25
- package/dist/esm/components/nav/CNavGroup.js.map +1 -1
- package/dist/esm/components/nav/CNavGroupContext.d.ts +25 -0
- package/dist/esm/components/nav/CNavGroupContext.js +11 -0
- package/dist/esm/components/nav/CNavGroupContext.js.map +1 -0
- package/dist/esm/components/nav/CNavLink.d.ts +1 -5
- package/dist/esm/components/nav/CNavLink.js +21 -8
- package/dist/esm/components/nav/CNavLink.js.map +1 -1
- package/dist/esm/components/popover/CPopover.js +57 -9
- package/dist/esm/components/popover/CPopover.js.map +1 -1
- package/dist/esm/components/progress/CProgress.js.map +1 -1
- package/dist/esm/components/rating/CRating.d.ts +1 -1
- package/dist/esm/components/rating/CRating.js.map +1 -1
- package/dist/esm/components/sidebar/CSidebar.js +40 -23
- package/dist/esm/components/sidebar/CSidebar.js.map +1 -1
- package/dist/esm/components/sidebar/CSidebarNav.js +7 -36
- package/dist/esm/components/sidebar/CSidebarNav.js.map +1 -1
- package/dist/esm/components/table/CTableDataCell.js.map +1 -1
- package/dist/esm/components/table/types.d.ts +2 -1
- package/dist/esm/components/table/utils.js +4 -4
- package/dist/esm/components/table/utils.js.map +1 -1
- package/dist/esm/components/tabs/CTabPanel.js +3 -1
- package/dist/esm/components/tabs/CTabPanel.js.map +1 -1
- package/dist/esm/components/tooltip/CTooltip.js +57 -9
- package/dist/esm/components/tooltip/CTooltip.js.map +1 -1
- package/dist/esm/helpers/polymorphicComponent.d.ts +1 -2
- package/dist/esm/hooks/useForkedRef.d.ts +1 -1
- package/dist/esm/hooks/useForkedRef.js +6 -3
- package/dist/esm/hooks/useForkedRef.js.map +1 -1
- package/dist/esm/hooks/usePopper.js +9 -7
- package/dist/esm/hooks/usePopper.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +1 -1
- package/dist/esm/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js.map +1 -1
- package/dist/esm/node_modules/ua-parser-js/dist/ua-parser.min.js +3 -3
- package/dist/esm/node_modules/ua-parser-js/dist/ua-parser.min.js.map +1 -1
- package/dist/esm/utils/executeAfterTransition.js.map +1 -1
- package/dist/esm/utils/index.d.ts +2 -1
- package/dist/esm/utils/swipe.d.ts +26 -0
- package/dist/esm/utils/swipe.js +90 -0
- package/dist/esm/utils/swipe.js.map +1 -0
- package/package.json +6 -6
- package/src/components/autocomplete/CAutocompleteOptions.tsx +1 -1
- package/src/components/card/CCardImage.tsx +3 -2
- package/src/components/carousel/CCarousel.tsx +48 -51
- package/src/components/carousel/CCarouselContext.ts +1 -1
- package/src/components/carousel/CCarouselItem.tsx +25 -26
- package/src/components/carousel/__tests__/CCarousel.spec.tsx +47 -4
- package/src/components/carousel/__tests__/CCarouselItem.spec.tsx +37 -0
- package/src/components/chip/CChip.tsx +45 -78
- package/src/components/chip/__tests__/CChip.spec.tsx +26 -19
- package/src/components/chip/const.ts +3 -0
- package/src/components/chip-set/CChipSet.tsx +183 -0
- package/src/components/chip-set/__tests__/CChipSet.spec.tsx +215 -0
- package/src/components/chip-set/__tests__/__snapshots__/CChipSet.spec.tsx.snap +22 -0
- package/src/components/chip-set/index.ts +3 -0
- package/src/components/chip-set/useChipSet.ts +243 -0
- package/src/components/chip-set/utils.ts +19 -0
- package/src/components/collapse/CCollapse.tsx +18 -6
- package/src/components/conditional-portal/CConditionalPortal.tsx +4 -2
- package/src/components/dropdown/CDropdown.tsx +28 -33
- package/src/components/dropdown/CDropdownToggle.tsx +1 -1
- package/src/components/dropdown/__tests__/CDropdown.spec.tsx +55 -0
- package/src/components/focus-trap/__tests__/CFocusTrap.spec.tsx +1 -1
- package/src/components/form/CChipInput.tsx +105 -67
- package/src/components/form/CFormCheck.tsx +1 -2
- package/src/components/form/CFormInput.tsx +1 -2
- package/src/components/form/CFormSelect.tsx +1 -2
- package/src/components/form/CFormTextarea.tsx +1 -2
- package/src/components/form/CInputGroupText.tsx +3 -2
- package/src/components/form/__tests__/CChipInput.spec.tsx +67 -1
- package/src/components/form/__tests__/__snapshots__/CChipInput.spec.tsx.snap +7 -0
- package/src/components/grid/CContainer.tsx +3 -1
- package/src/components/header/CHeaderBrand.tsx +3 -2
- package/src/components/index.ts +1 -0
- package/src/components/link/CLink.tsx +7 -4
- package/src/components/list-group/CListGroupItem.tsx +3 -2
- package/src/components/modal/CModal.tsx +19 -2
- package/src/components/modal/__tests__/CModal.spec.tsx +43 -0
- package/src/components/multi-select/CMultiSelect.tsx +341 -46
- package/src/components/multi-select/CMultiSelectNativeSelect.tsx +1 -1
- package/src/components/multi-select/CMultiSelectOptions.tsx +74 -3
- package/src/components/multi-select/CMultiSelectSelection.tsx +5 -1
- package/src/components/multi-select/__tests__/CMultiSelect.spec.tsx +12 -8
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelect.spec.tsx.snap +62 -45
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectNativeSelect.spec.tsx.snap +2 -2
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectOptions.spec.tsx.snap +1 -0
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectSelection.spec.tsx.snap +5 -1
- package/src/components/multi-select/types.ts +14 -0
- package/src/components/nav/CNav.tsx +3 -2
- package/src/components/nav/CNavGroup.tsx +193 -107
- package/src/components/nav/CNavGroupContext.ts +27 -0
- package/src/components/nav/CNavLink.tsx +26 -12
- package/src/components/nav/__tests__/CNavGroup.spec.tsx +195 -20
- package/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.tsx.snap +2 -0
- package/src/components/popover/CPopover.tsx +59 -9
- package/src/components/popover/__tests__/CPopover.spec.tsx +76 -1
- package/src/components/progress/CProgress.tsx +1 -2
- package/src/components/rating/CRating.tsx +1 -0
- package/src/components/search-button/__tests__/CSearchButton.spec.tsx +2 -2
- package/src/components/sidebar/CSidebar.tsx +51 -26
- package/src/components/sidebar/CSidebarNav.tsx +12 -51
- package/src/components/sidebar/__tests__/CSidebar.spec.tsx +26 -0
- package/src/components/table/CTableDataCell.tsx +2 -1
- package/src/components/table/types.ts +3 -1
- package/src/components/table/utils.ts +4 -4
- package/src/components/tabs/CTabPanel.tsx +3 -1
- package/src/components/tabs/CTabsContext.ts +1 -1
- package/src/components/tooltip/CTooltip.tsx +59 -9
- package/src/components/tooltip/__tests__/CTooltip.spec.tsx +96 -1
- package/src/helpers/polymorphicComponent.ts +1 -1
- package/src/hooks/useColorModes.ts +2 -2
- package/src/hooks/useForkedRef.ts +20 -15
- package/src/hooks/usePopper.ts +13 -9
- package/src/utils/__tests__/swipe.spec.ts +82 -0
- package/src/utils/executeAfterTransition.ts +1 -1
- package/src/utils/index.ts +2 -0
- package/src/utils/mergeClassNames.ts +1 -1
- package/src/utils/swipe.ts +114 -0
- package/dist/cjs/components/sidebar/CSidebarNavContext.d.ts +0 -5
- package/dist/cjs/components/sidebar/CSidebarNavContext.js +0 -8
- package/dist/cjs/components/sidebar/CSidebarNavContext.js.map +0 -1
- package/dist/esm/components/sidebar/CSidebarNavContext.d.ts +0 -5
- package/dist/esm/components/sidebar/CSidebarNavContext.js +0 -6
- package/dist/esm/components/sidebar/CSidebarNavContext.js.map +0 -1
- package/src/components/sidebar/CSidebarNavContext.ts +0 -8
|
@@ -2,18 +2,14 @@ import React, {
|
|
|
2
2
|
ElementType,
|
|
3
3
|
forwardRef,
|
|
4
4
|
HTMLAttributes,
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
useCallback,
|
|
6
|
+
useMemo,
|
|
7
7
|
useState,
|
|
8
8
|
} from 'react'
|
|
9
9
|
import PropTypes from 'prop-types'
|
|
10
10
|
import classNames from 'classnames'
|
|
11
11
|
|
|
12
|
-
import
|
|
13
|
-
import type { CNavLinkProps } from '../nav/CNavLink'
|
|
14
|
-
import type { CNavItemProps } from '../nav/CNavItem'
|
|
15
|
-
|
|
16
|
-
import { CSidebarNavContext } from './CSidebarNavContext'
|
|
12
|
+
import { CNavGroupContext, CNavGroupContextValue } from '../nav/CNavGroupContext'
|
|
17
13
|
|
|
18
14
|
import { PolymorphicRefForwardingComponent } from '../../helpers'
|
|
19
15
|
|
|
@@ -42,54 +38,19 @@ export interface CSidebarNavProps extends HTMLAttributes<HTMLUListElement> {
|
|
|
42
38
|
variant?: 'tree'
|
|
43
39
|
}
|
|
44
40
|
|
|
45
|
-
const isNavElement = (
|
|
46
|
-
child: ReactNode
|
|
47
|
-
): child is ReactElement<CNavGroupProps | CNavLinkProps | CNavItemProps> => {
|
|
48
|
-
if (!React.isValidElement(child)) return false
|
|
49
|
-
const type = child.type as { displayName?: string }
|
|
50
|
-
return (
|
|
51
|
-
type.displayName === 'CNavGroup' ||
|
|
52
|
-
type.displayName === 'CNavLink' ||
|
|
53
|
-
type.displayName === 'CNavItem'
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const recursiveClone = (children: ReactNode, id?: string, updateId?: boolean): ReactNode => {
|
|
58
|
-
return React.Children.map(children, (child, index) => {
|
|
59
|
-
if (!isNavElement(child)) {
|
|
60
|
-
return child
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const _id = id ? (updateId ? `${id}.${index}` : `${id}`) : `${index}`
|
|
64
|
-
|
|
65
|
-
if (child.props.children) {
|
|
66
|
-
const type = child.type as { displayName?: string }
|
|
67
|
-
const shouldUpdateId = type.displayName !== 'CNavItem'
|
|
68
|
-
|
|
69
|
-
return React.cloneElement(child, {
|
|
70
|
-
idx: _id,
|
|
71
|
-
children: recursiveClone(child.props.children, _id, shouldUpdateId),
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return React.cloneElement(child, {
|
|
76
|
-
idx: _id,
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
|
|
81
41
|
export const CSidebarNav: PolymorphicRefForwardingComponent<'ul', CSidebarNavProps> = forwardRef<
|
|
82
42
|
HTMLUListElement,
|
|
83
43
|
CSidebarNavProps
|
|
84
44
|
>(({ children, as: Component = 'ul', className, compact, variant, ...rest }, ref) => {
|
|
85
|
-
const [
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
45
|
+
const [activeId, setActiveId] = useState<string | undefined>()
|
|
46
|
+
const openBranch = useCallback(() => {}, [])
|
|
47
|
+
const contextValue = useMemo<CNavGroupContextValue>(
|
|
48
|
+
() => ({ activeId, setActiveId, openBranch }),
|
|
49
|
+
[activeId, openBranch]
|
|
50
|
+
)
|
|
90
51
|
|
|
91
52
|
return (
|
|
92
|
-
<
|
|
53
|
+
<CNavGroupContext.Provider value={contextValue}>
|
|
93
54
|
<Component
|
|
94
55
|
className={classNames(
|
|
95
56
|
'sidebar-nav',
|
|
@@ -102,9 +63,9 @@ export const CSidebarNav: PolymorphicRefForwardingComponent<'ul', CSidebarNavPro
|
|
|
102
63
|
ref={ref}
|
|
103
64
|
{...rest}
|
|
104
65
|
>
|
|
105
|
-
{
|
|
66
|
+
{children}
|
|
106
67
|
</Component>
|
|
107
|
-
</
|
|
68
|
+
</CNavGroupContext.Provider>
|
|
108
69
|
)
|
|
109
70
|
})
|
|
110
71
|
|
|
@@ -44,3 +44,29 @@ test('CSidebar customize hide', async () => {
|
|
|
44
44
|
expect(container.firstChild).toHaveClass('sidebar')
|
|
45
45
|
expect(container.firstChild).toHaveClass('sidebar-sticky')
|
|
46
46
|
})
|
|
47
|
+
|
|
48
|
+
test('CSidebar removes the exact transitionend listener reference on cleanup', async () => {
|
|
49
|
+
const addSpy = jest.spyOn(HTMLElement.prototype, 'addEventListener')
|
|
50
|
+
const removeSpy = jest.spyOn(HTMLElement.prototype, 'removeEventListener')
|
|
51
|
+
|
|
52
|
+
const { container, unmount } = render(<CSidebar>Test</CSidebar>)
|
|
53
|
+
const sidebar = container.querySelector('.sidebar')
|
|
54
|
+
unmount()
|
|
55
|
+
|
|
56
|
+
const handlersOn = (spy: jest.SpyInstance) =>
|
|
57
|
+
spy.mock.calls
|
|
58
|
+
.map((args, index) => ({ args, context: spy.mock.contexts[index] }))
|
|
59
|
+
.filter(({ args, context }) => args[0] === 'transitionend' && context === sidebar)
|
|
60
|
+
.map(({ args }) => args[1])
|
|
61
|
+
|
|
62
|
+
const added = handlersOn(addSpy)
|
|
63
|
+
const removed = handlersOn(removeSpy)
|
|
64
|
+
|
|
65
|
+
expect(added.length).toBeGreaterThan(0)
|
|
66
|
+
for (const handler of added) {
|
|
67
|
+
expect(removed).toContain(handler)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
addSpy.mockRestore()
|
|
71
|
+
removeSpy.mockRestore()
|
|
72
|
+
})
|
|
@@ -6,7 +6,8 @@ import { colorPropType } from '../../props'
|
|
|
6
6
|
import type { Colors } from '../../types'
|
|
7
7
|
|
|
8
8
|
export interface CTableDataCellProps
|
|
9
|
-
extends
|
|
9
|
+
extends
|
|
10
|
+
Omit<TdHTMLAttributes<HTMLTableCellElement>, 'align'>,
|
|
10
11
|
Omit<ThHTMLAttributes<HTMLTableCellElement>, 'align'> {
|
|
11
12
|
/**
|
|
12
13
|
* Highlight a table row or cell.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { CSSProperties } from 'react'
|
|
2
|
+
|
|
1
3
|
import { CTableDataCellProps } from '../table/CTableDataCell'
|
|
2
4
|
import { CTableHeaderCellProps } from '../table/CTableHeaderCell'
|
|
3
5
|
import { CTableRowProps } from '../table/CTableRow'
|
|
@@ -5,7 +7,7 @@ import { CTableRowProps } from '../table/CTableRow'
|
|
|
5
7
|
export type Column = {
|
|
6
8
|
label?: string
|
|
7
9
|
key: string
|
|
8
|
-
_style?:
|
|
10
|
+
_style?: CSSProperties
|
|
9
11
|
_props?: CTableHeaderCellProps
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -2,16 +2,16 @@ import type { Column, Item } from './types'
|
|
|
2
2
|
|
|
3
3
|
export const pretifyName = (name: string) => {
|
|
4
4
|
return name
|
|
5
|
-
.
|
|
6
|
-
.
|
|
7
|
-
.
|
|
5
|
+
.replaceAll(/[-_.]/g, ' ')
|
|
6
|
+
.replaceAll(/ +/g, ' ')
|
|
7
|
+
.replaceAll(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
8
8
|
.split(' ')
|
|
9
9
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
10
10
|
.join(' ')
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export const getColumnLabel = (column: Column | string) =>
|
|
14
|
-
typeof column === 'object' ? column.label ?? pretifyName(column.key) : pretifyName(column)
|
|
14
|
+
typeof column === 'object' ? (column.label ?? pretifyName(column.key)) : pretifyName(column)
|
|
15
15
|
|
|
16
16
|
export const getColumnNames = (columns: (string | Column)[] | undefined, items?: Item[]) =>
|
|
17
17
|
columns
|
|
@@ -44,7 +44,9 @@ export const CTabPanel = forwardRef<HTMLDivElement, CTabPanelProps>(
|
|
|
44
44
|
const [_visible, setVisible] = useState(visible || _activeItemKey === itemKey)
|
|
45
45
|
|
|
46
46
|
useEffect(() => {
|
|
47
|
-
visible !== undefined
|
|
47
|
+
if (visible !== undefined) {
|
|
48
|
+
setVisible(visible)
|
|
49
|
+
}
|
|
48
50
|
}, [visible])
|
|
49
51
|
|
|
50
52
|
useEffect(() => {
|
|
@@ -173,6 +173,14 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
|
|
|
173
173
|
const { initPopper, destroyPopper, updatePopper } = usePopper()
|
|
174
174
|
|
|
175
175
|
const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay
|
|
176
|
+
const timer = useRef<ReturnType<typeof setTimeout>>(undefined)
|
|
177
|
+
|
|
178
|
+
const clearTimer = () => {
|
|
179
|
+
if (timer.current) {
|
|
180
|
+
clearTimeout(timer.current)
|
|
181
|
+
timer.current = undefined
|
|
182
|
+
}
|
|
183
|
+
}
|
|
176
184
|
|
|
177
185
|
const defaultPopperConfig: Partial<Options> = {
|
|
178
186
|
modifiers: [
|
|
@@ -189,12 +197,23 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
|
|
|
189
197
|
}
|
|
190
198
|
|
|
191
199
|
const handleShow = () => {
|
|
192
|
-
|
|
200
|
+
clearTimer()
|
|
201
|
+
|
|
202
|
+
if (mounted) {
|
|
203
|
+
timer.current = setTimeout(() => {
|
|
204
|
+
setVisible(true)
|
|
205
|
+
}, _delay.show)
|
|
206
|
+
} else {
|
|
207
|
+
setMounted(true)
|
|
208
|
+
}
|
|
209
|
+
|
|
193
210
|
onShow?.()
|
|
194
211
|
}
|
|
195
212
|
|
|
196
213
|
const handleHide = () => {
|
|
197
|
-
|
|
214
|
+
clearTimer()
|
|
215
|
+
|
|
216
|
+
timer.current = setTimeout(() => {
|
|
198
217
|
setVisible(false)
|
|
199
218
|
onHide?.()
|
|
200
219
|
}, _delay.hide)
|
|
@@ -211,7 +230,7 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
|
|
|
211
230
|
useEffect(() => {
|
|
212
231
|
if (mounted && togglerRef.current && tooltipRef.current) {
|
|
213
232
|
initPopper(togglerRef.current, tooltipRef.current, computedPopperConfig)
|
|
214
|
-
setTimeout(() => {
|
|
233
|
+
timer.current = setTimeout(() => {
|
|
215
234
|
setVisible(true)
|
|
216
235
|
}, _delay.show)
|
|
217
236
|
|
|
@@ -223,6 +242,13 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
|
|
|
223
242
|
}
|
|
224
243
|
}, [mounted])
|
|
225
244
|
|
|
245
|
+
useEffect(() => {
|
|
246
|
+
return () => {
|
|
247
|
+
clearTimer()
|
|
248
|
+
destroyPopper()
|
|
249
|
+
}
|
|
250
|
+
}, [])
|
|
251
|
+
|
|
226
252
|
useEffect(() => {
|
|
227
253
|
if (!_visible && togglerRef.current && tooltipRef.current) {
|
|
228
254
|
executeAfterTransition(() => {
|
|
@@ -235,23 +261,47 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
|
|
|
235
261
|
updatePopper()
|
|
236
262
|
}, [content])
|
|
237
263
|
|
|
264
|
+
const child = children as React.ReactElement<
|
|
265
|
+
React.HTMLAttributes<HTMLElement> & { ref?: React.Ref<HTMLElement> }
|
|
266
|
+
>
|
|
267
|
+
|
|
238
268
|
return (
|
|
239
269
|
<>
|
|
240
|
-
{React.cloneElement(
|
|
270
|
+
{React.cloneElement(child, {
|
|
241
271
|
...(_visible && {
|
|
242
272
|
'aria-describedby': id,
|
|
243
273
|
}),
|
|
244
274
|
ref: togglerRef,
|
|
245
275
|
...((trigger === 'click' || trigger.includes('click')) && {
|
|
246
|
-
onClick: () =>
|
|
276
|
+
onClick: (event: React.MouseEvent<HTMLElement>) => {
|
|
277
|
+
child.props.onClick?.(event)
|
|
278
|
+
|
|
279
|
+
if (_visible) {
|
|
280
|
+
handleHide()
|
|
281
|
+
} else {
|
|
282
|
+
handleShow()
|
|
283
|
+
}
|
|
284
|
+
},
|
|
247
285
|
}),
|
|
248
286
|
...((trigger === 'focus' || trigger.includes('focus')) && {
|
|
249
|
-
onFocus: () =>
|
|
250
|
-
|
|
287
|
+
onFocus: (event: React.FocusEvent<HTMLElement>) => {
|
|
288
|
+
child.props.onFocus?.(event)
|
|
289
|
+
handleShow()
|
|
290
|
+
},
|
|
291
|
+
onBlur: (event: React.FocusEvent<HTMLElement>) => {
|
|
292
|
+
child.props.onBlur?.(event)
|
|
293
|
+
handleHide()
|
|
294
|
+
},
|
|
251
295
|
}),
|
|
252
296
|
...((trigger === 'hover' || trigger.includes('hover')) && {
|
|
253
|
-
onMouseEnter: () =>
|
|
254
|
-
|
|
297
|
+
onMouseEnter: (event: React.MouseEvent<HTMLElement>) => {
|
|
298
|
+
child.props.onMouseEnter?.(event)
|
|
299
|
+
handleShow()
|
|
300
|
+
},
|
|
301
|
+
onMouseLeave: (event: React.MouseEvent<HTMLElement>) => {
|
|
302
|
+
child.props.onMouseLeave?.(event)
|
|
303
|
+
handleHide()
|
|
304
|
+
},
|
|
255
305
|
}),
|
|
256
306
|
})}
|
|
257
307
|
<CConditionalPortal container={container} portal={true}>
|
|
@@ -13,7 +13,7 @@ beforeEach(() => {
|
|
|
13
13
|
})
|
|
14
14
|
|
|
15
15
|
afterEach(() => {
|
|
16
|
-
container
|
|
16
|
+
container?.remove()
|
|
17
17
|
container = null
|
|
18
18
|
})
|
|
19
19
|
|
|
@@ -47,6 +47,101 @@ test('CTooltip customize', async () => {
|
|
|
47
47
|
jest.useRealTimers()
|
|
48
48
|
})
|
|
49
49
|
|
|
50
|
+
test('CTooltip stays visible when re-hovered during the hide delay', async () => {
|
|
51
|
+
jest.useFakeTimers()
|
|
52
|
+
|
|
53
|
+
render(
|
|
54
|
+
<CTooltip trigger="hover" delay={{ show: 0, hide: 300 }} content="content">
|
|
55
|
+
<CLink>Test</CLink>
|
|
56
|
+
</CTooltip>
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const link = screen.getByText('Test')
|
|
60
|
+
|
|
61
|
+
act(() => {
|
|
62
|
+
fireEvent.mouseOver(link)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
act(() => {
|
|
66
|
+
jest.runAllTimers()
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
expect(document.querySelector('.tooltip')).toHaveClass('show')
|
|
70
|
+
|
|
71
|
+
act(() => {
|
|
72
|
+
fireEvent.mouseOut(link)
|
|
73
|
+
jest.advanceTimersByTime(100)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
act(() => {
|
|
77
|
+
fireEvent.mouseOver(link)
|
|
78
|
+
jest.advanceTimersByTime(1000)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
expect(document.querySelector('.tooltip')).toHaveClass('show')
|
|
82
|
+
|
|
83
|
+
jest.useRealTimers()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test('CTooltip cancels the pending show timer when pointer leaves before the show delay', async () => {
|
|
87
|
+
jest.useFakeTimers()
|
|
88
|
+
|
|
89
|
+
render(
|
|
90
|
+
<CTooltip trigger="hover" delay={{ show: 300, hide: 0 }} content="content">
|
|
91
|
+
<CLink>Test</CLink>
|
|
92
|
+
</CTooltip>
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
const link = screen.getByText('Test')
|
|
96
|
+
|
|
97
|
+
act(() => {
|
|
98
|
+
fireEvent.mouseOver(link)
|
|
99
|
+
jest.advanceTimersByTime(100)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
act(() => {
|
|
103
|
+
fireEvent.mouseOut(link)
|
|
104
|
+
jest.advanceTimersByTime(1000)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
expect(document.querySelector('.tooltip.show')).toBeNull()
|
|
108
|
+
expect(link).not.toHaveAttribute('aria-describedby')
|
|
109
|
+
|
|
110
|
+
jest.useRealTimers()
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
test('CTooltip preserves event handlers of the child element', async () => {
|
|
114
|
+
jest.useFakeTimers()
|
|
115
|
+
|
|
116
|
+
const onClick = jest.fn()
|
|
117
|
+
const onMouseEnter = jest.fn()
|
|
118
|
+
|
|
119
|
+
render(
|
|
120
|
+
<CTooltip trigger={['hover', 'click']} content="content">
|
|
121
|
+
<CButton onClick={onClick} onMouseEnter={onMouseEnter}>
|
|
122
|
+
Test
|
|
123
|
+
</CButton>
|
|
124
|
+
</CTooltip>
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
const btn = screen.getByRole('button', { name: /test/i })
|
|
128
|
+
|
|
129
|
+
act(() => {
|
|
130
|
+
fireEvent.mouseOver(btn)
|
|
131
|
+
jest.runAllTimers()
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
act(() => {
|
|
135
|
+
fireEvent.click(btn)
|
|
136
|
+
jest.runAllTimers()
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
expect(onMouseEnter).toHaveBeenCalledTimes(1)
|
|
140
|
+
expect(onClick).toHaveBeenCalledTimes(1)
|
|
141
|
+
|
|
142
|
+
jest.useRealTimers()
|
|
143
|
+
})
|
|
144
|
+
|
|
50
145
|
test('CTooltip onShow and onHide', async () => {
|
|
51
146
|
jest.useFakeTimers()
|
|
52
147
|
|
|
@@ -8,7 +8,7 @@ export interface AsProp<As extends ElementType = ElementType> {
|
|
|
8
8
|
as?: As
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export
|
|
11
|
+
export type Props<As extends ElementType = ElementType> = AsProp<As>
|
|
12
12
|
|
|
13
13
|
export interface PolymorphicRefForwardingComponent<TInitial extends ElementType, P = unknown> {
|
|
14
14
|
<As extends ElementType = TInitial>(
|
|
@@ -37,10 +37,10 @@ const setTheme = (colorMode: string) => {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export const useColorModes = (
|
|
40
|
-
localStorageItemName = 'coreui-react-color-scheme'
|
|
40
|
+
localStorageItemName = 'coreui-react-color-scheme'
|
|
41
41
|
): UseColorModesOutput => {
|
|
42
42
|
const [colorMode, setColorMode] = useState<string | undefined>(
|
|
43
|
-
getPreferredColorScheme(localStorageItemName)
|
|
43
|
+
getPreferredColorScheme(localStorageItemName)
|
|
44
44
|
)
|
|
45
45
|
|
|
46
46
|
useEffect(() => {
|
|
@@ -13,24 +13,30 @@ export type AssignableRef<ValueType> =
|
|
|
13
13
|
export function useForkedRef<RefValueType = any>(
|
|
14
14
|
...refs: (AssignableRef<RefValueType> | null | undefined)[]
|
|
15
15
|
) {
|
|
16
|
-
return useMemo(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
return useMemo(
|
|
17
|
+
() => {
|
|
18
|
+
if (refs.every((ref) => ref == null)) {
|
|
19
|
+
return null
|
|
20
|
+
}
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
return (node: any) => {
|
|
23
|
+
refs.forEach((ref) => {
|
|
24
|
+
assignRef(ref, node)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
// useForkedRef accepts a variable number of refs, so the dependency list
|
|
29
|
+
// cannot be a static array literal; the refs are compared element-wise.
|
|
30
|
+
// eslint-disable-next-line react-hooks/use-memo, react-hooks/exhaustive-deps
|
|
31
|
+
refs
|
|
32
|
+
)
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
36
|
export function assignRef<RefValueType = any>(
|
|
31
37
|
ref: AssignableRef<RefValueType> | null | undefined,
|
|
32
38
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
-
value: any
|
|
39
|
+
value: any
|
|
34
40
|
) {
|
|
35
41
|
if (ref == null) return
|
|
36
42
|
if (isFunction(ref)) {
|
|
@@ -44,7 +50,6 @@ export function assignRef<RefValueType = any>(
|
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return !!(value && {}.toString.call(value) == '[object Function]')
|
|
53
|
+
export function isFunction(value: unknown): value is (...args: unknown[]) => unknown {
|
|
54
|
+
return typeof value === 'function'
|
|
50
55
|
}
|
package/src/hooks/usePopper.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRef } from 'react'
|
|
1
|
+
import { useCallback, useRef } from 'react'
|
|
2
2
|
import { createPopper } from '@popperjs/core'
|
|
3
3
|
import type { Instance, Options } from '@popperjs/core'
|
|
4
4
|
|
|
@@ -13,12 +13,16 @@ export const usePopper = (): UsePopperOutput => {
|
|
|
13
13
|
const _popper = useRef<Instance>(undefined)
|
|
14
14
|
const el = useRef<HTMLElement>(null)
|
|
15
15
|
|
|
16
|
-
const initPopper = (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
const initPopper = useCallback(
|
|
17
|
+
(reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => {
|
|
18
|
+
_popper.current?.destroy()
|
|
19
|
+
_popper.current = createPopper(reference, popper, options)
|
|
20
|
+
el.current = popper
|
|
21
|
+
},
|
|
22
|
+
[]
|
|
23
|
+
)
|
|
20
24
|
|
|
21
|
-
const destroyPopper = () => {
|
|
25
|
+
const destroyPopper = useCallback(() => {
|
|
22
26
|
const popperInstance = _popper.current
|
|
23
27
|
|
|
24
28
|
if (popperInstance && el.current) {
|
|
@@ -26,9 +30,9 @@ export const usePopper = (): UsePopperOutput => {
|
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
_popper.current = undefined
|
|
29
|
-
}
|
|
33
|
+
}, [])
|
|
30
34
|
|
|
31
|
-
const updatePopper = (options?: Partial<Options>) => {
|
|
35
|
+
const updatePopper = useCallback((options?: Partial<Options>) => {
|
|
32
36
|
const popperInstance = _popper.current
|
|
33
37
|
|
|
34
38
|
if (popperInstance && options) {
|
|
@@ -38,7 +42,7 @@ export const usePopper = (): UsePopperOutput => {
|
|
|
38
42
|
if (popperInstance) {
|
|
39
43
|
popperInstance.update()
|
|
40
44
|
}
|
|
41
|
-
}
|
|
45
|
+
}, [])
|
|
42
46
|
|
|
43
47
|
return {
|
|
44
48
|
popper: _popper.current,
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import Swipe from '../swipe'
|
|
2
|
+
|
|
3
|
+
const touchEvent = (type: string, clientX: number): Event => {
|
|
4
|
+
const event = new Event(type) as Event & { touches: { clientX: number }[] }
|
|
5
|
+
event.touches = [{ clientX }]
|
|
6
|
+
return event
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe('Swipe', () => {
|
|
10
|
+
let element: HTMLElement
|
|
11
|
+
const originalPointerEvent = window.PointerEvent
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
element = document.createElement('div')
|
|
15
|
+
document.body.appendChild(element)
|
|
16
|
+
// Force the touch-event path and make the helper consider touch supported.
|
|
17
|
+
;(window as unknown as { PointerEvent?: unknown }).PointerEvent = undefined
|
|
18
|
+
Object.defineProperty(navigator, 'maxTouchPoints', { value: 1, configurable: true })
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
element.remove()
|
|
23
|
+
;(window as unknown as { PointerEvent?: unknown }).PointerEvent = originalPointerEvent
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('reports support when touch points are available', () => {
|
|
27
|
+
expect(Swipe.isSupported()).toBe(true)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('calls onLeft when swiping left past the threshold', () => {
|
|
31
|
+
const onLeft = jest.fn()
|
|
32
|
+
const onRight = jest.fn()
|
|
33
|
+
const onEnd = jest.fn()
|
|
34
|
+
new Swipe(element, { onLeft, onRight, onEnd })
|
|
35
|
+
|
|
36
|
+
element.dispatchEvent(touchEvent('touchstart', 200))
|
|
37
|
+
element.dispatchEvent(touchEvent('touchmove', 100))
|
|
38
|
+
element.dispatchEvent(touchEvent('touchend', 100))
|
|
39
|
+
|
|
40
|
+
expect(onLeft).toHaveBeenCalledTimes(1)
|
|
41
|
+
expect(onRight).not.toHaveBeenCalled()
|
|
42
|
+
expect(onEnd).toHaveBeenCalledTimes(1)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('calls onRight when swiping right past the threshold', () => {
|
|
46
|
+
const onLeft = jest.fn()
|
|
47
|
+
const onRight = jest.fn()
|
|
48
|
+
new Swipe(element, { onLeft, onRight })
|
|
49
|
+
|
|
50
|
+
element.dispatchEvent(touchEvent('touchstart', 100))
|
|
51
|
+
element.dispatchEvent(touchEvent('touchmove', 200))
|
|
52
|
+
element.dispatchEvent(touchEvent('touchend', 200))
|
|
53
|
+
|
|
54
|
+
expect(onRight).toHaveBeenCalledTimes(1)
|
|
55
|
+
expect(onLeft).not.toHaveBeenCalled()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('ignores swipes below the threshold', () => {
|
|
59
|
+
const onLeft = jest.fn()
|
|
60
|
+
const onRight = jest.fn()
|
|
61
|
+
new Swipe(element, { onLeft, onRight })
|
|
62
|
+
|
|
63
|
+
element.dispatchEvent(touchEvent('touchstart', 200))
|
|
64
|
+
element.dispatchEvent(touchEvent('touchmove', 180))
|
|
65
|
+
element.dispatchEvent(touchEvent('touchend', 180))
|
|
66
|
+
|
|
67
|
+
expect(onLeft).not.toHaveBeenCalled()
|
|
68
|
+
expect(onRight).not.toHaveBeenCalled()
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('stops detecting swipes after dispose', () => {
|
|
72
|
+
const onLeft = jest.fn()
|
|
73
|
+
const swipe = new Swipe(element, { onLeft })
|
|
74
|
+
swipe.dispose()
|
|
75
|
+
|
|
76
|
+
element.dispatchEvent(touchEvent('touchstart', 200))
|
|
77
|
+
element.dispatchEvent(touchEvent('touchmove', 100))
|
|
78
|
+
element.dispatchEvent(touchEvent('touchend', 100))
|
|
79
|
+
|
|
80
|
+
expect(onLeft).not.toHaveBeenCalled()
|
|
81
|
+
})
|
|
82
|
+
})
|
package/src/utils/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import isInViewport from './isInViewport'
|
|
|
8
8
|
import isObjectInArray from './isObjectInArray'
|
|
9
9
|
import isRTL from './isRTL'
|
|
10
10
|
import mergeClassNames from './mergeClassNames'
|
|
11
|
+
import Swipe from './swipe'
|
|
11
12
|
|
|
12
13
|
export {
|
|
13
14
|
executeAfterTransition,
|
|
@@ -20,4 +21,5 @@ export {
|
|
|
20
21
|
isObjectInArray,
|
|
21
22
|
isRTL,
|
|
22
23
|
mergeClassNames,
|
|
24
|
+
Swipe,
|
|
23
25
|
}
|
|
@@ -9,7 +9,7 @@ const mergeClassNames = <T extends object>(
|
|
|
9
9
|
const classNames: T = { ...defaultClassNames }
|
|
10
10
|
|
|
11
11
|
for (const key in customClassNames) {
|
|
12
|
-
if (
|
|
12
|
+
if (Object.hasOwn(customClassNames, key)) {
|
|
13
13
|
const typedKey = key as keyof T
|
|
14
14
|
const customClassName = customClassNames[typedKey]?.toString()
|
|
15
15
|
|