@coreui/react-pro 5.24.1 → 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/README.md +1 -1
- 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/date-picker/CDatePicker.d.ts +1 -1
- package/dist/cjs/components/date-picker/CDatePicker.js.map +1 -1
- package/dist/cjs/components/date-range-picker/CDateRangePicker.js +2 -0
- package/dist/cjs/components/date-range-picker/CDateRangePicker.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdown.js +23 -30
- 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 +2 -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 +13 -6
- package/dist/cjs/components/nav/CNavGroup.js +86 -23
- 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/one-time-password-input/COneTimePassword.js +3 -3
- package/dist/cjs/components/one-time-password-input/COneTimePassword.js.map +1 -1
- package/dist/cjs/components/popover/CPopover.js +69 -24
- 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/search-button/CSearchButton.d.ts +32 -0
- package/dist/cjs/components/search-button/CSearchButton.js +77 -0
- package/dist/cjs/components/search-button/CSearchButton.js.map +1 -0
- package/dist/cjs/components/search-button/index.d.ts +2 -0
- package/dist/cjs/components/search-button/types.d.ts +10 -0
- package/dist/cjs/components/search-button/utils.d.ts +11 -0
- package/dist/cjs/components/search-button/utils.js +115 -0
- package/dist/cjs/components/search-button/utils.js.map +1 -0
- 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.d.ts +12 -0
- package/dist/cjs/components/sidebar/CSidebarNav.js +12 -36
- package/dist/cjs/components/sidebar/CSidebarNav.js.map +1 -1
- package/dist/cjs/components/smart-table/CSmartTable.js +2 -2
- package/dist/cjs/components/smart-table/CSmartTable.js.map +1 -1
- package/dist/cjs/components/smart-table/CSmartTableInterface.d.ts +2 -2
- 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/time-picker/CTimePicker.d.ts +1 -1
- package/dist/cjs/components/time-picker/CTimePicker.js +1 -1
- package/dist/cjs/components/time-picker/CTimePicker.js.map +1 -1
- package/dist/cjs/components/tooltip/CTooltip.js +69 -24
- package/dist/cjs/components/tooltip/CTooltip.js.map +1 -1
- package/dist/cjs/components/virtual-scroller/CVirtualScroller.js +11 -8
- package/dist/cjs/components/virtual-scroller/CVirtualScroller.js.map +1 -1
- package/dist/cjs/helpers/polymorphicComponent.d.ts +1 -2
- package/dist/cjs/hooks/useDebouncedCallback.d.ts +1 -1
- package/dist/cjs/hooks/useDebouncedCallback.js +1 -1
- package/dist/cjs/hooks/useDebouncedCallback.js.map +1 -1
- 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 +4 -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/@coreui/icons/dist/esm/free/cil-arrow-bottom.js +1 -1
- package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js.map +1 -1
- package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js +1 -1
- package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js.map +1 -1
- package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js +1 -1
- package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js.map +1 -1
- package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js +1 -1
- package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js.map +1 -1
- package/dist/cjs/node_modules/ua-parser-js/dist/ua-parser.min.js +4 -4
- 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/date-picker/CDatePicker.d.ts +1 -1
- package/dist/esm/components/date-picker/CDatePicker.js.map +1 -1
- package/dist/esm/components/date-range-picker/CDateRangePicker.js +2 -0
- package/dist/esm/components/date-range-picker/CDateRangePicker.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdown.js +23 -30
- 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 +2 -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 +13 -6
- package/dist/esm/components/nav/CNavGroup.js +87 -24
- 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/one-time-password-input/COneTimePassword.js +3 -3
- package/dist/esm/components/one-time-password-input/COneTimePassword.js.map +1 -1
- package/dist/esm/components/popover/CPopover.js +69 -24
- 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/search-button/CSearchButton.d.ts +32 -0
- package/dist/esm/components/search-button/CSearchButton.js +75 -0
- package/dist/esm/components/search-button/CSearchButton.js.map +1 -0
- package/dist/esm/components/search-button/index.d.ts +2 -0
- package/dist/esm/components/search-button/types.d.ts +10 -0
- package/dist/esm/components/search-button/utils.d.ts +11 -0
- package/dist/esm/components/search-button/utils.js +104 -0
- package/dist/esm/components/search-button/utils.js.map +1 -0
- 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.d.ts +12 -0
- package/dist/esm/components/sidebar/CSidebarNav.js +13 -37
- package/dist/esm/components/sidebar/CSidebarNav.js.map +1 -1
- package/dist/esm/components/smart-table/CSmartTable.js +2 -2
- package/dist/esm/components/smart-table/CSmartTable.js.map +1 -1
- package/dist/esm/components/smart-table/CSmartTableInterface.d.ts +2 -2
- 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/time-picker/CTimePicker.d.ts +1 -1
- package/dist/esm/components/time-picker/CTimePicker.js +1 -1
- package/dist/esm/components/time-picker/CTimePicker.js.map +1 -1
- package/dist/esm/components/tooltip/CTooltip.js +69 -24
- package/dist/esm/components/tooltip/CTooltip.js.map +1 -1
- package/dist/esm/components/virtual-scroller/CVirtualScroller.js +11 -8
- package/dist/esm/components/virtual-scroller/CVirtualScroller.js.map +1 -1
- package/dist/esm/helpers/polymorphicComponent.d.ts +1 -2
- package/dist/esm/hooks/useDebouncedCallback.d.ts +1 -1
- package/dist/esm/hooks/useDebouncedCallback.js +1 -1
- package/dist/esm/hooks/useDebouncedCallback.js.map +1 -1
- 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 +2 -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/@coreui/icons/dist/esm/free/cil-arrow-bottom.js +1 -1
- package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js.map +1 -1
- package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js +1 -1
- package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js.map +1 -1
- package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js +1 -1
- package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js.map +1 -1
- package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js +1 -1
- package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js.map +1 -1
- package/dist/esm/node_modules/ua-parser-js/dist/ua-parser.min.js +4 -4
- 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 +8 -6
- package/src/components/autocomplete/CAutocompleteOptions.tsx +1 -1
- package/src/components/autocomplete/__tests__/CAutocomplete.spec.tsx +18 -16
- package/src/components/autocomplete/__tests__/CAutocompleteOptions.spec.tsx +37 -28
- package/src/components/autocomplete/__tests__/__snapshots__/CAutocomplete.spec.tsx.snap +129 -0
- package/src/components/autocomplete/__tests__/__snapshots__/CAutocompleteOptions.spec.tsx.snap +36 -0
- package/src/components/calendar/__tests__/CCalendar.spec.tsx +40 -45
- package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +99 -75
- package/src/components/calendar/__tests__/utils.spec.tsx +8 -18
- 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/date-picker/CDatePicker.tsx +12 -13
- package/src/components/date-picker/__tests__/CDatePicker.spec.tsx +1 -1
- package/src/components/date-picker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +12 -640
- package/src/components/date-range-picker/CDateRangePicker.tsx +2 -0
- package/src/components/date-range-picker/__tests__/CDateRangePicker.spec.tsx +1 -1
- package/src/components/date-range-picker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +21 -1259
- package/src/components/dropdown/CDropdown.tsx +29 -34
- package/src/components/dropdown/CDropdownToggle.tsx +1 -1
- package/src/components/dropdown/__tests__/CDropdown.spec.tsx +56 -1
- package/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap +2 -2
- package/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap +1 -1
- 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__/CFormInput.spec.tsx +17 -20
- package/src/components/form/__tests__/__snapshots__/CChipInput.spec.tsx.snap +7 -0
- package/src/components/form/__tests__/__snapshots__/CFormInput.spec.tsx.snap +12 -3
- package/src/components/grid/CContainer.tsx +3 -1
- package/src/components/header/CHeaderBrand.tsx +3 -2
- package/src/components/index.ts +2 -0
- package/src/components/link/CLink.tsx +7 -4
- package/src/components/list-group/CListGroupItem.tsx +3 -2
- package/src/components/loading-button/__tests__/CLoadingButton.spec.tsx +1 -1
- package/src/components/loading-button/__tests__/__snapshots__/CLoadingButton.spec.tsx.snap +4 -4
- 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 +27 -69
- package/src/components/multi-select/__tests__/CMultiSelectNativeSelect.spec.tsx +4 -5
- package/src/components/multi-select/__tests__/CMultiSelectOptions.spec.tsx +4 -4
- package/src/components/multi-select/__tests__/CMultiSelectSelection.spec.tsx +7 -24
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelect.spec.tsx.snap +108 -61
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectNativeSelect.spec.tsx.snap +2 -4
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectOptions.spec.tsx.snap +7 -0
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectSelection.spec.tsx.snap +16 -9
- package/src/components/multi-select/types.ts +14 -0
- package/src/components/nav/CNav.tsx +3 -2
- package/src/components/nav/CNavGroup.tsx +196 -105
- package/src/components/nav/CNavGroupContext.ts +27 -0
- package/src/components/nav/CNavLink.tsx +26 -12
- package/src/components/nav/__tests__/CNavGroup.spec.tsx +207 -4
- package/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.tsx.snap +3 -1
- package/src/components/offcanvas/__tests__/COffcanvas.spec.tsx +1 -0
- package/src/components/one-time-password-input/COneTimePassword.tsx +10 -11
- package/src/components/picker/__tests__/CPicker.spec.tsx +1 -1
- package/src/components/picker/__tests__/__snapshots__/CPicker.spec.tsx.snap +2 -16
- package/src/components/popover/CPopover.tsx +71 -26
- package/src/components/popover/__tests__/CPopover.spec.tsx +85 -4
- package/src/components/progress/CProgress.tsx +1 -2
- package/src/components/rating/CRating.tsx +1 -0
- package/src/components/search-button/CSearchButton.tsx +195 -0
- package/src/components/search-button/__tests__/CSearchButton.spec.tsx +95 -0
- package/src/components/search-button/__tests__/__snapshots__/CSearchButton.spec.tsx.snap +87 -0
- package/src/components/search-button/index.ts +3 -0
- package/src/components/search-button/types.ts +10 -0
- package/src/components/search-button/utils.ts +140 -0
- package/src/components/sidebar/CSidebar.tsx +51 -26
- package/src/components/sidebar/CSidebarNav.tsx +39 -53
- package/src/components/sidebar/__tests__/CSidebar.spec.tsx +26 -0
- package/src/components/smart-table/CSmartTable.tsx +5 -4
- package/src/components/smart-table/CSmartTableInterface.tsx +2 -2
- package/src/components/smart-table/__tests__/CSmartTable.spec.tsx +3 -2
- package/src/components/smart-table/__tests__/__snapshots__/CSmartTable.spec.tsx.snap +7 -15
- package/src/components/stepper/__tests__/CStepper.spec.tsx +24 -21
- package/src/components/stepper/__tests__/__snapshots__/CStepper.spec.tsx.snap +295 -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/tabs/__tests__/CTabContent.spec.tsx +1 -0
- package/src/components/tabs/__tests__/CTabPane.spec.tsx +1 -0
- package/src/components/time-picker/CTimePicker.tsx +6 -7
- package/src/components/time-picker/__tests__/CTimePicker.spec.tsx +10 -1
- package/src/components/time-picker/__tests__/__snapshots__/CTimePicker.spec.tsx.snap +599 -315
- package/src/components/tooltip/CTooltip.tsx +72 -27
- package/src/components/tooltip/__tests__/CTooltip.spec.tsx +102 -1
- package/src/components/virtual-scroller/CVirtualScroller.tsx +13 -14
- package/src/helpers/polymorphicComponent.ts +1 -1
- package/src/hooks/useColorModes.ts +2 -2
- package/src/hooks/useDebouncedCallback.ts +7 -4
- 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/accordion/CAccordionCollapse.d.ts +0 -3
- 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/accordion/CAccordionCollapse.d.ts +0 -3
- 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/accordion/CAccordionCollapse.tsx +0 -20
- package/src/components/accordion/__tests__/CAccordionCollapse.spec.tsx +0 -10
- package/src/components/accordion/__tests__/__snapshots__/CAccordionCollapse.spec.tsx.snap +0 -11
- package/src/components/button/__tests__/__snapshots__/CButtonClose.spec.tsx.snap +0 -26
- package/src/components/calendar/__tests__/CCalendar.accessibility.spec.tsx +0 -595
- package/src/components/calendar/__tests__/CCalendar.comprehensive.spec.tsx +0 -402
- package/src/components/calendar/__tests__/CCalendar.edge-cases.spec.tsx +0 -416
- package/src/components/calendar/__tests__/CCalendar.interactions.spec.tsx +0 -593
- package/src/components/header/CHeaderBrand.tsx~HEAD +0 -36
- package/src/components/sidebar/CSidebarNavContext.ts +0 -8
- /package/src/components/calendar/__tests__/{test-setup.ts → setup.ts} +0 -0
|
@@ -4,8 +4,11 @@ import React, {
|
|
|
4
4
|
forwardRef,
|
|
5
5
|
HTMLAttributes,
|
|
6
6
|
ReactNode,
|
|
7
|
+
useCallback,
|
|
7
8
|
useContext,
|
|
8
9
|
useEffect,
|
|
10
|
+
useId,
|
|
11
|
+
useMemo,
|
|
9
12
|
useRef,
|
|
10
13
|
useState,
|
|
11
14
|
} from 'react'
|
|
@@ -16,8 +19,7 @@ import type { TransitionStatus } from 'react-transition-group'
|
|
|
16
19
|
|
|
17
20
|
import { PolymorphicRefForwardingComponent } from '../../helpers'
|
|
18
21
|
|
|
19
|
-
import {
|
|
20
|
-
|
|
22
|
+
import { CNavGroupContext, CNavGroupContextValue } from './CNavGroupContext'
|
|
21
23
|
export interface CNavGroupProps extends HTMLAttributes<HTMLDivElement | HTMLLIElement> {
|
|
22
24
|
/**
|
|
23
25
|
* Component used for the root node. Either a string to use a HTML element or a component.
|
|
@@ -34,140 +36,229 @@ export interface CNavGroupProps extends HTMLAttributes<HTMLDivElement | HTMLLIEl
|
|
|
34
36
|
*/
|
|
35
37
|
compact?: boolean
|
|
36
38
|
/**
|
|
37
|
-
*
|
|
39
|
+
* Callback fired when the user toggles the group. Receives the requested visibility. Provide
|
|
40
|
+
* it together with `visible` for controlled mode—update `visible` from here, or ignore the
|
|
41
|
+
* change to keep the group as is.
|
|
42
|
+
*
|
|
43
|
+
* @since 5.12.0
|
|
38
44
|
*/
|
|
39
|
-
|
|
45
|
+
onVisibleChange?: (visible: boolean) => void
|
|
40
46
|
/**
|
|
41
|
-
*
|
|
47
|
+
* Set group toggler label.
|
|
42
48
|
*/
|
|
43
|
-
|
|
49
|
+
toggler?: string | ReactNode | (({ visible }: { visible: boolean }) => ReactNode)
|
|
44
50
|
/**
|
|
45
|
-
*
|
|
51
|
+
* Show nav group items. Acts as the initial state when used on its own, or as the controlled
|
|
52
|
+
* value when paired with `onVisibleChange`.
|
|
46
53
|
*/
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const isInVisibleGroup = (el1: string, el2: string) => {
|
|
51
|
-
const array1 = el1.toString().split('.')
|
|
52
|
-
const array2 = el2.toString().split('.')
|
|
53
|
-
|
|
54
|
-
return array2.every((item, index) => item === array1[index])
|
|
54
|
+
visible?: boolean
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export const CNavGroup: PolymorphicRefForwardingComponent<'li', CNavGroupProps> = forwardRef<
|
|
58
58
|
HTMLDivElement | HTMLLIElement,
|
|
59
59
|
CNavGroupProps
|
|
60
|
-
>(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
>(
|
|
61
|
+
(
|
|
62
|
+
{
|
|
63
|
+
children,
|
|
64
|
+
as: Component = 'li',
|
|
65
|
+
className,
|
|
66
|
+
compact,
|
|
67
|
+
onVisibleChange,
|
|
68
|
+
toggler,
|
|
69
|
+
visible,
|
|
70
|
+
...rest
|
|
71
|
+
},
|
|
72
|
+
ref
|
|
73
|
+
) => {
|
|
74
|
+
const id = useId()
|
|
75
|
+
|
|
76
|
+
// Accordion of the parent level: lets this group read whether it is the open one and request
|
|
77
|
+
// its own open/close. `null` when rendered outside a `CSidebarNav`.
|
|
78
|
+
const parentContext = useContext(CNavGroupContext)
|
|
79
|
+
const parentContextRef = useRef(parentContext)
|
|
80
|
+
parentContextRef.current = parentContext
|
|
81
|
+
|
|
82
|
+
const [height, setHeight] = useState<number | string>(0)
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
+
const navItemsRef = useRef<any>(null)
|
|
85
|
+
|
|
86
|
+
const [uncontrolledVisible, setUncontrolledVisible] = useState(Boolean(visible))
|
|
87
|
+
// This group's own accordion state for its children. It survives the group being collapsed,
|
|
88
|
+
// so reopening the group restores whichever child was previously open.
|
|
89
|
+
const [activeChildId, setActiveChildId] = useState<string | undefined>()
|
|
90
|
+
|
|
91
|
+
const controlled = visible !== undefined && onVisibleChange !== undefined
|
|
92
|
+
|
|
93
|
+
const _visible = controlled
|
|
94
|
+
? Boolean(visible)
|
|
95
|
+
: parentContext
|
|
96
|
+
? parentContext.activeId === id
|
|
97
|
+
: uncontrolledVisible
|
|
98
|
+
|
|
99
|
+
// Sync the accordion with the `visible` prop: seeds default-open groups and follows later
|
|
100
|
+
// changes (and keeps controlled groups in sync). Watching only `visible` keeps this from
|
|
101
|
+
// re-running on unrelated accordion updates—so a default-open group can be collapsed manually.
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (visible === undefined) {
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const parentSetActiveId = parentContextRef.current?.setActiveId
|
|
108
|
+
if (parentSetActiveId) {
|
|
109
|
+
if (visible) {
|
|
110
|
+
parentSetActiveId(id)
|
|
111
|
+
} else {
|
|
112
|
+
parentSetActiveId((prev) => (prev === id ? undefined : prev))
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
setUncontrolledVisible(visible)
|
|
116
|
+
}
|
|
117
|
+
}, [visible, id])
|
|
64
118
|
|
|
65
|
-
|
|
119
|
+
// Accordion: when another branch opens, a controlled group must close too. As its visibility
|
|
120
|
+
// is owned by the parent, request the change through `onVisibleChange`.
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (!controlled || !visible) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
66
125
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
126
|
+
const activeId = parentContext?.activeId
|
|
127
|
+
if (activeId !== undefined && activeId !== id) {
|
|
128
|
+
onVisibleChange?.(false)
|
|
129
|
+
}
|
|
130
|
+
}, [controlled, visible, parentContext?.activeId, id, onVisibleChange])
|
|
70
131
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
132
|
+
// Open this group within its parent level and cascade up to the root, revealing the whole
|
|
133
|
+
// branch. Used by an active nav link and by nested groups to bubble the request upwards.
|
|
134
|
+
const openBranch = useCallback(() => {
|
|
135
|
+
const parent = parentContextRef.current
|
|
136
|
+
if (!parent) {
|
|
137
|
+
return
|
|
138
|
+
}
|
|
74
139
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
140
|
+
parent.setActiveId(id)
|
|
141
|
+
parent.openBranch()
|
|
142
|
+
}, [id])
|
|
143
|
+
|
|
144
|
+
const childContextValue = useMemo<CNavGroupContextValue>(
|
|
145
|
+
() => ({ activeId: activeChildId, setActiveId: setActiveChildId, openBranch }),
|
|
146
|
+
[activeChildId, openBranch]
|
|
79
147
|
)
|
|
80
|
-
setVisible(!_visible)
|
|
81
|
-
}
|
|
82
148
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
149
|
+
const handleTogglerOnClick = (event: React.MouseEvent<HTMLElement>) => {
|
|
150
|
+
event.preventDefault()
|
|
151
|
+
const next = !_visible
|
|
86
152
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
153
|
+
if (!controlled) {
|
|
154
|
+
if (parentContext) {
|
|
155
|
+
parentContext.setActiveId(next ? id : undefined)
|
|
156
|
+
} else {
|
|
157
|
+
setUncontrolledVisible(next)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
90
160
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
161
|
+
onVisibleChange?.(next)
|
|
162
|
+
}
|
|
94
163
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
164
|
+
const style: CSSProperties = {
|
|
165
|
+
height: 0,
|
|
166
|
+
}
|
|
98
167
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
168
|
+
const onEntering = () => {
|
|
169
|
+
if (navItemsRef.current) {
|
|
170
|
+
setHeight(navItemsRef.current.scrollHeight)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
105
173
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
174
|
+
const onEntered = () => {
|
|
175
|
+
setHeight('auto')
|
|
176
|
+
}
|
|
109
177
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
178
|
+
const onExit = () => {
|
|
179
|
+
if (navItemsRef.current) {
|
|
180
|
+
setHeight(navItemsRef.current.scrollHeight)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const onExiting = () => {
|
|
185
|
+
// @ts-expect-error reflow is necessary to get correct height of the element
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
187
|
+
const reflow = navItemsRef.current?.offsetHeight
|
|
188
|
+
setHeight(0)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const onExited = () => {
|
|
192
|
+
setHeight(0)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const transitionStyles = {
|
|
196
|
+
entering: { display: 'block', height: height },
|
|
197
|
+
entered: { display: 'block', height: height },
|
|
198
|
+
exiting: { display: 'block', height: height },
|
|
199
|
+
exited: { height: height },
|
|
200
|
+
unmounted: {},
|
|
201
|
+
}
|
|
117
202
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<a
|
|
128
|
-
className="nav-link nav-group-toggle"
|
|
129
|
-
href="#"
|
|
130
|
-
onClick={(event) => handleTogglerOnCLick(event)}
|
|
203
|
+
const NavGroupItemsComponent = Component === 'li' ? 'ul' : 'div'
|
|
204
|
+
const togglerContent = typeof toggler === 'function' ? toggler({ visible: _visible }) : toggler
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<CNavGroupContext.Provider value={childContextValue}>
|
|
208
|
+
<Component
|
|
209
|
+
className={classNames('nav-group', { show: _visible }, className)}
|
|
210
|
+
{...rest}
|
|
211
|
+
ref={ref}
|
|
131
212
|
>
|
|
132
|
-
{toggler
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
...transitionStyles[state as TransitionStatus],
|
|
153
|
-
}}
|
|
154
|
-
ref={navItemsRef}
|
|
213
|
+
{toggler && (
|
|
214
|
+
<a
|
|
215
|
+
aria-expanded={_visible}
|
|
216
|
+
className="nav-link nav-group-toggle"
|
|
217
|
+
href="#"
|
|
218
|
+
onClick={handleTogglerOnClick}
|
|
219
|
+
>
|
|
220
|
+
{togglerContent}
|
|
221
|
+
</a>
|
|
222
|
+
)}
|
|
223
|
+
<Transition
|
|
224
|
+
appear
|
|
225
|
+
in={_visible}
|
|
226
|
+
nodeRef={navItemsRef}
|
|
227
|
+
onEntering={onEntering}
|
|
228
|
+
onEntered={onEntered}
|
|
229
|
+
onExit={onExit}
|
|
230
|
+
onExiting={onExiting}
|
|
231
|
+
onExited={onExited}
|
|
232
|
+
timeout={300}
|
|
155
233
|
>
|
|
156
|
-
{
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
234
|
+
{(state) => (
|
|
235
|
+
<NavGroupItemsComponent
|
|
236
|
+
className={classNames('nav-group-items', {
|
|
237
|
+
compact: compact,
|
|
238
|
+
})}
|
|
239
|
+
style={{
|
|
240
|
+
...style,
|
|
241
|
+
...transitionStyles[state as TransitionStatus],
|
|
242
|
+
}}
|
|
243
|
+
ref={navItemsRef}
|
|
244
|
+
>
|
|
245
|
+
{children}
|
|
246
|
+
</NavGroupItemsComponent>
|
|
247
|
+
)}
|
|
248
|
+
</Transition>
|
|
249
|
+
</Component>
|
|
250
|
+
</CNavGroupContext.Provider>
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
)
|
|
163
254
|
|
|
164
255
|
CNavGroup.propTypes = {
|
|
165
256
|
as: PropTypes.elementType,
|
|
166
257
|
children: PropTypes.node,
|
|
167
258
|
className: PropTypes.string,
|
|
168
259
|
compact: PropTypes.bool,
|
|
169
|
-
|
|
170
|
-
toggler: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
260
|
+
onVisibleChange: PropTypes.func,
|
|
261
|
+
toggler: PropTypes.oneOfType([PropTypes.string, PropTypes.node, PropTypes.func]),
|
|
171
262
|
visible: PropTypes.bool,
|
|
172
263
|
}
|
|
173
264
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createContext, Dispatch, SetStateAction } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface CNavGroupContextValue {
|
|
4
|
+
/**
|
|
5
|
+
* The id of the currently open child group at this level, or `undefined` when none is open.
|
|
6
|
+
* Each `CNavGroup` keeps its own accordion state, so collapsing an ancestor never discards the
|
|
7
|
+
* open/closed state of its descendants—reopening the ancestor restores them.
|
|
8
|
+
*/
|
|
9
|
+
activeId: string | undefined
|
|
10
|
+
/**
|
|
11
|
+
* Open (or, with `undefined`, close) a child group at this level. Opening a group collapses its
|
|
12
|
+
* siblings, mirroring the vanilla `groupsAutoCollapse` behavior.
|
|
13
|
+
*/
|
|
14
|
+
setActiveId: Dispatch<SetStateAction<string | undefined>>
|
|
15
|
+
/**
|
|
16
|
+
* Open the whole branch from the parent group up to the root. Used by an active nav link to
|
|
17
|
+
* reveal every ancestor group.
|
|
18
|
+
*/
|
|
19
|
+
openBranch: () => void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Provides the per-level accordion state to the direct children (`CNavGroup`, `CNavLink`) of a
|
|
24
|
+
* `CSidebarNav` or a parent `CNavGroup`. `null` means the consumer is rendered outside a sidebar
|
|
25
|
+
* navigation, in which case groups fall back to their own local state.
|
|
26
|
+
*/
|
|
27
|
+
export const CNavGroupContext = createContext<CNavGroupContextValue | null>(null)
|
|
@@ -3,16 +3,12 @@ import PropTypes from 'prop-types'
|
|
|
3
3
|
import classNames from 'classnames'
|
|
4
4
|
|
|
5
5
|
import { CLinkProps, CLink } from '../link/CLink'
|
|
6
|
-
import {
|
|
6
|
+
import { CNavGroupContext } from './CNavGroupContext'
|
|
7
7
|
|
|
8
8
|
import { PolymorphicRefForwardingComponent } from '../../helpers'
|
|
9
9
|
import { useForkedRef } from '../../hooks'
|
|
10
10
|
|
|
11
|
-
export interface CNavLinkProps extends
|
|
12
|
-
/**
|
|
13
|
-
* @ignore
|
|
14
|
-
*/
|
|
15
|
-
idx?: string
|
|
11
|
+
export interface CNavLinkProps extends CLinkProps {
|
|
16
12
|
/**
|
|
17
13
|
* @ignore
|
|
18
14
|
*/
|
|
@@ -22,16 +18,35 @@ export interface CNavLinkProps extends Omit<CLinkProps, 'idx'> {
|
|
|
22
18
|
export const CNavLink: PolymorphicRefForwardingComponent<'a', CNavLinkProps> = forwardRef<
|
|
23
19
|
HTMLButtonElement | HTMLAnchorElement,
|
|
24
20
|
CNavLinkProps
|
|
25
|
-
>(({ children, className,
|
|
21
|
+
>(({ children, className, ...rest }, ref) => {
|
|
26
22
|
const navLinkRef = useRef<HTMLAnchorElement>(null)
|
|
27
23
|
const forkedRef = useForkedRef(ref, navLinkRef)
|
|
28
24
|
|
|
29
|
-
const
|
|
25
|
+
const openBranch = useContext(CNavGroupContext)?.openBranch
|
|
30
26
|
|
|
31
27
|
useEffect(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
const element = navLinkRef.current
|
|
29
|
+
|
|
30
|
+
if (!element || !openBranch) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let wasActive = false
|
|
35
|
+
const sync = () => {
|
|
36
|
+
const active = element.classList.contains('active')
|
|
37
|
+
if (active && !wasActive) {
|
|
38
|
+
openBranch()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
wasActive = active
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
sync()
|
|
45
|
+
const observer = new MutationObserver(sync)
|
|
46
|
+
observer.observe(element, { attributes: true, attributeFilter: ['class'] })
|
|
47
|
+
|
|
48
|
+
return () => observer.disconnect()
|
|
49
|
+
}, [openBranch])
|
|
35
50
|
|
|
36
51
|
return (
|
|
37
52
|
<CLink className={classNames('nav-link', className)} {...rest} ref={forkedRef}>
|
|
@@ -46,7 +61,6 @@ CNavLink.propTypes = {
|
|
|
46
61
|
children: PropTypes.node,
|
|
47
62
|
className: PropTypes.string,
|
|
48
63
|
disabled: PropTypes.bool,
|
|
49
|
-
idx: PropTypes.string,
|
|
50
64
|
}
|
|
51
65
|
|
|
52
66
|
CNavLink.displayName = 'CNavLink'
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
|
-
import { render } from '@testing-library/react'
|
|
2
|
+
import { fireEvent, render, screen } from '@testing-library/react'
|
|
3
3
|
import '@testing-library/jest-dom'
|
|
4
|
-
import { CNavGroup } from '../index'
|
|
4
|
+
import { CNavGroup, CNavItem } from '../index'
|
|
5
|
+
import { CSidebarNav } from '../../sidebar/CSidebarNav'
|
|
5
6
|
|
|
6
7
|
test('loads and displays CNavGroup component', async () => {
|
|
7
8
|
const { container } = render(<CNavGroup toggler="anchorText" />)
|
|
@@ -10,16 +11,218 @@ test('loads and displays CNavGroup component', async () => {
|
|
|
10
11
|
|
|
11
12
|
test('CNavGroup customize', async () => {
|
|
12
13
|
const { container } = render(
|
|
13
|
-
<CNavGroup className="bazinga" toggler="anchorText" visible={true}
|
|
14
|
+
<CNavGroup className="bazinga" toggler="anchorText" visible={true} />
|
|
14
15
|
)
|
|
15
16
|
expect(container).toMatchSnapshot()
|
|
16
17
|
expect(container.firstChild).toHaveClass('nav-group')
|
|
17
18
|
expect(container.firstChild).toHaveClass('bazinga')
|
|
18
19
|
const arr = container.getElementsByClassName('nav-link')
|
|
19
20
|
if (arr.length > 0) {
|
|
20
|
-
//expect(arr[0].innerText).toHaveTextContent('anchorText')
|
|
21
21
|
expect(arr[0].innerHTML).toBe('anchorText')
|
|
22
22
|
} else {
|
|
23
23
|
expect(true).toBe(false)
|
|
24
24
|
}
|
|
25
25
|
})
|
|
26
|
+
|
|
27
|
+
test('CNavGroup toggles its own visibility when uncontrolled', async () => {
|
|
28
|
+
const { container } = render(
|
|
29
|
+
<CSidebarNav>
|
|
30
|
+
<CNavGroup toggler="anchorText">
|
|
31
|
+
<CNavItem href="#">Item</CNavItem>
|
|
32
|
+
</CNavGroup>
|
|
33
|
+
</CSidebarNav>
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
const group = container.querySelector('.nav-group') as HTMLElement
|
|
37
|
+
expect(group).not.toHaveClass('show')
|
|
38
|
+
|
|
39
|
+
fireEvent.click(container.querySelector('.nav-group-toggle') as HTMLElement)
|
|
40
|
+
expect(group).toHaveClass('show')
|
|
41
|
+
|
|
42
|
+
fireEvent.click(container.querySelector('.nav-group-toggle') as HTMLElement)
|
|
43
|
+
expect(group).not.toHaveClass('show')
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('CNavGroup follows the visible prop in controlled mode', async () => {
|
|
47
|
+
const { container, rerender } = render(<CNavGroup toggler="anchorText" visible={true} />)
|
|
48
|
+
expect(container.querySelector('.nav-group')).toHaveClass('show')
|
|
49
|
+
|
|
50
|
+
rerender(<CNavGroup toggler="anchorText" visible={false} />)
|
|
51
|
+
expect(container.querySelector('.nav-group')).not.toHaveClass('show')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('CNavGroup stays open when the parent rejects the collapse (controlled)', async () => {
|
|
55
|
+
const onVisibleChange = jest.fn()
|
|
56
|
+
const { container } = render(
|
|
57
|
+
<CNavGroup toggler="anchorText" visible={true} onVisibleChange={onVisibleChange} />
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
expect(container.querySelector('.nav-group')).toHaveClass('show')
|
|
61
|
+
|
|
62
|
+
// Parent keeps `visible` at `true` (rejects the collapse).
|
|
63
|
+
fireEvent.click(container.querySelector('.nav-group-toggle') as HTMLElement)
|
|
64
|
+
|
|
65
|
+
expect(onVisibleChange).toHaveBeenCalledWith(false)
|
|
66
|
+
expect(container.querySelector('.nav-group')).toHaveClass('show')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
test('CNavGroup toggler render function receives visible state', async () => {
|
|
70
|
+
render(<CNavGroup toggler={({ visible }) => <span>{visible ? 'expanded' : 'collapsed'}</span>} />)
|
|
71
|
+
|
|
72
|
+
expect(screen.getByText('collapsed')).toBeInTheDocument()
|
|
73
|
+
|
|
74
|
+
fireEvent.click(screen.getByRole('link'))
|
|
75
|
+
|
|
76
|
+
expect(screen.getByText('expanded')).toBeInTheDocument()
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('an active nav link opens its parent group', async () => {
|
|
80
|
+
const { container } = render(
|
|
81
|
+
<CSidebarNav>
|
|
82
|
+
<CNavGroup toggler="anchorText">
|
|
83
|
+
<CNavItem href="#" active>
|
|
84
|
+
Item
|
|
85
|
+
</CNavItem>
|
|
86
|
+
</CNavGroup>
|
|
87
|
+
</CSidebarNav>
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
expect(container.querySelector('.nav-group')).toHaveClass('show')
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
test('opening another group closes a controlled group when the parent accepts', async () => {
|
|
94
|
+
const Wrapper = () => {
|
|
95
|
+
const [visible, setVisible] = React.useState(true)
|
|
96
|
+
return (
|
|
97
|
+
<CSidebarNav>
|
|
98
|
+
<CNavGroup toggler="Controlled" visible={visible} onVisibleChange={setVisible}>
|
|
99
|
+
<CNavItem href="#">A</CNavItem>
|
|
100
|
+
</CNavGroup>
|
|
101
|
+
<CNavGroup toggler="Other">
|
|
102
|
+
<CNavItem href="#">B</CNavItem>
|
|
103
|
+
</CNavGroup>
|
|
104
|
+
</CSidebarNav>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const { container } = render(<Wrapper />)
|
|
109
|
+
const [controlled, other] = Array.from(container.querySelectorAll('.nav-group'))
|
|
110
|
+
expect(controlled).toHaveClass('show')
|
|
111
|
+
|
|
112
|
+
fireEvent.click(container.querySelectorAll('.nav-group-toggle')[1] as HTMLElement)
|
|
113
|
+
|
|
114
|
+
expect(other).toHaveClass('show')
|
|
115
|
+
expect(controlled).not.toHaveClass('show')
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
test('a locked controlled group stays open when another group opens', async () => {
|
|
119
|
+
const Wrapper = () => {
|
|
120
|
+
const [visible, setVisible] = React.useState(true)
|
|
121
|
+
const onVisibleChange = (value: boolean) => {
|
|
122
|
+
if (value) {
|
|
123
|
+
setVisible(true)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return (
|
|
127
|
+
<CSidebarNav>
|
|
128
|
+
<CNavGroup toggler="Locked" visible={visible} onVisibleChange={onVisibleChange}>
|
|
129
|
+
<CNavItem href="#">A</CNavItem>
|
|
130
|
+
</CNavGroup>
|
|
131
|
+
<CNavGroup toggler="Other">
|
|
132
|
+
<CNavItem href="#">B</CNavItem>
|
|
133
|
+
</CNavGroup>
|
|
134
|
+
</CSidebarNav>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const { container } = render(<Wrapper />)
|
|
139
|
+
const [locked, other] = Array.from(container.querySelectorAll('.nav-group'))
|
|
140
|
+
expect(locked).toHaveClass('show')
|
|
141
|
+
|
|
142
|
+
fireEvent.click(container.querySelectorAll('.nav-group-toggle')[1] as HTMLElement)
|
|
143
|
+
|
|
144
|
+
expect(other).toHaveClass('show')
|
|
145
|
+
expect(locked).toHaveClass('show')
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
test('opening an uncontrolled group collapses its sibling', async () => {
|
|
149
|
+
const { container } = render(
|
|
150
|
+
<CSidebarNav>
|
|
151
|
+
<CNavGroup toggler="A">
|
|
152
|
+
<CNavItem href="#">Item</CNavItem>
|
|
153
|
+
</CNavGroup>
|
|
154
|
+
<CNavGroup toggler="B">
|
|
155
|
+
<CNavItem href="#">Item</CNavItem>
|
|
156
|
+
</CNavGroup>
|
|
157
|
+
</CSidebarNav>
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
const [groupA, groupB] = Array.from(container.querySelectorAll('.nav-group'))
|
|
161
|
+
const [togglerA, togglerB] = Array.from(container.querySelectorAll('.nav-group-toggle'))
|
|
162
|
+
|
|
163
|
+
fireEvent.click(togglerA as HTMLElement)
|
|
164
|
+
expect(groupA).toHaveClass('show')
|
|
165
|
+
expect(groupB).not.toHaveClass('show')
|
|
166
|
+
|
|
167
|
+
fireEvent.click(togglerB as HTMLElement)
|
|
168
|
+
expect(groupA).not.toHaveClass('show')
|
|
169
|
+
expect(groupB).toHaveClass('show')
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
test('reopening a parent restores the open state of its nested subgroups', async () => {
|
|
173
|
+
const { container } = render(
|
|
174
|
+
<CSidebarNav>
|
|
175
|
+
<CNavGroup toggler="A" visible>
|
|
176
|
+
<CNavGroup toggler="B" visible>
|
|
177
|
+
<CNavGroup toggler="C" visible>
|
|
178
|
+
<CNavItem href="#">Item</CNavItem>
|
|
179
|
+
</CNavGroup>
|
|
180
|
+
</CNavGroup>
|
|
181
|
+
</CNavGroup>
|
|
182
|
+
</CSidebarNav>
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
const [groupA, groupB, groupC] = Array.from(container.querySelectorAll('.nav-group'))
|
|
186
|
+
expect(groupA).toHaveClass('show')
|
|
187
|
+
expect(groupB).toHaveClass('show')
|
|
188
|
+
expect(groupC).toHaveClass('show')
|
|
189
|
+
|
|
190
|
+
const outerToggler = container.querySelectorAll('.nav-group-toggle')[0] as HTMLElement
|
|
191
|
+
|
|
192
|
+
// Collapse the parent: the whole branch is hidden.
|
|
193
|
+
fireEvent.click(outerToggler)
|
|
194
|
+
expect(groupA).not.toHaveClass('show')
|
|
195
|
+
|
|
196
|
+
// Reopen the parent: nested subgroups come back open (matches vanilla/Vue).
|
|
197
|
+
fireEvent.click(outerToggler)
|
|
198
|
+
expect(groupA).toHaveClass('show')
|
|
199
|
+
expect(groupB).toHaveClass('show')
|
|
200
|
+
expect(groupC).toHaveClass('show')
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
test('nested default-open groups render open and stay independently toggleable', async () => {
|
|
204
|
+
const { container } = render(
|
|
205
|
+
<CSidebarNav>
|
|
206
|
+
<CNavGroup toggler="Group A" visible>
|
|
207
|
+
<CNavGroup toggler="Group B" visible>
|
|
208
|
+
<CNavItem href="#">Item</CNavItem>
|
|
209
|
+
</CNavGroup>
|
|
210
|
+
</CNavGroup>
|
|
211
|
+
</CSidebarNav>
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
const [groupA, groupB] = Array.from(container.querySelectorAll('.nav-group'))
|
|
215
|
+
expect(groupA).toHaveClass('show')
|
|
216
|
+
expect(groupB).toHaveClass('show')
|
|
217
|
+
|
|
218
|
+
// Collapsing the inner group keeps the outer one open.
|
|
219
|
+
const innerToggler = container.querySelectorAll('.nav-group-toggle')[1] as HTMLElement
|
|
220
|
+
fireEvent.click(innerToggler)
|
|
221
|
+
expect(groupA).toHaveClass('show')
|
|
222
|
+
expect(groupB).not.toHaveClass('show')
|
|
223
|
+
|
|
224
|
+
// Collapsing the outer group closes the whole branch.
|
|
225
|
+
const outerToggler = container.querySelectorAll('.nav-group-toggle')[0] as HTMLElement
|
|
226
|
+
fireEvent.click(outerToggler)
|
|
227
|
+
expect(groupA).not.toHaveClass('show')
|
|
228
|
+
})
|