@coreui/react 5.0.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/components/button/CButton.js +5 -1
  3. package/dist/cjs/components/button/CButton.js.map +1 -1
  4. package/dist/cjs/components/dropdown/CDropdown.js +2 -1
  5. package/dist/cjs/components/dropdown/CDropdown.js.map +1 -1
  6. package/dist/cjs/components/dropdown/utils.d.ts +0 -1
  7. package/dist/cjs/components/dropdown/utils.js +0 -13
  8. package/dist/cjs/components/dropdown/utils.js.map +1 -1
  9. package/dist/cjs/components/popover/CPopover.js +47 -40
  10. package/dist/cjs/components/popover/CPopover.js.map +1 -1
  11. package/dist/cjs/components/tabs/CTab.d.ts +12 -0
  12. package/dist/cjs/components/tabs/CTab.js +25 -0
  13. package/dist/cjs/components/tabs/CTab.js.map +1 -0
  14. package/dist/cjs/components/tabs/CTabList.d.ts +16 -0
  15. package/dist/cjs/components/tabs/CTabList.js +54 -0
  16. package/dist/cjs/components/tabs/CTabList.js.map +1 -0
  17. package/dist/cjs/components/tabs/CTabPane.d.ts +6 -0
  18. package/dist/cjs/components/tabs/CTabPane.js +4 -2
  19. package/dist/cjs/components/tabs/CTabPane.js.map +1 -1
  20. package/dist/cjs/components/tabs/CTabPanel.d.ts +28 -0
  21. package/dist/cjs/components/tabs/CTabPanel.js +43 -0
  22. package/dist/cjs/components/tabs/CTabPanel.js.map +1 -0
  23. package/dist/cjs/components/tabs/CTabs.d.ts +22 -0
  24. package/dist/cjs/components/tabs/CTabs.js +28 -0
  25. package/dist/cjs/components/tabs/CTabs.js.map +1 -0
  26. package/dist/cjs/components/tabs/index.d.ts +5 -1
  27. package/dist/cjs/components/tooltip/CTooltip.js +50 -40
  28. package/dist/cjs/components/tooltip/CTooltip.js.map +1 -1
  29. package/dist/cjs/hooks/useForkedRef.d.ts +0 -1
  30. package/dist/cjs/hooks/usePopper.d.ts +1 -0
  31. package/dist/cjs/hooks/usePopper.js +11 -4
  32. package/dist/cjs/hooks/usePopper.js.map +1 -1
  33. package/dist/cjs/index.js +8 -0
  34. package/dist/cjs/index.js.map +1 -1
  35. package/dist/cjs/node_modules/react-transition-group/esm/CSSTransition.js +1 -2
  36. package/dist/cjs/node_modules/react-transition-group/esm/CSSTransition.js.map +1 -1
  37. package/dist/cjs/node_modules/react-transition-group/esm/Transition.js +1 -2
  38. package/dist/cjs/node_modules/react-transition-group/esm/Transition.js.map +1 -1
  39. package/dist/cjs/utils/getNextActiveElement.d.ts +2 -0
  40. package/dist/cjs/utils/getNextActiveElement.js +19 -0
  41. package/dist/cjs/utils/getNextActiveElement.js.map +1 -0
  42. package/dist/cjs/utils/index.d.ts +2 -1
  43. package/dist/esm/components/button/CButton.js +5 -1
  44. package/dist/esm/components/button/CButton.js.map +1 -1
  45. package/dist/esm/components/dropdown/CDropdown.js +2 -1
  46. package/dist/esm/components/dropdown/CDropdown.js.map +1 -1
  47. package/dist/esm/components/dropdown/utils.d.ts +0 -1
  48. package/dist/esm/components/dropdown/utils.js +1 -13
  49. package/dist/esm/components/dropdown/utils.js.map +1 -1
  50. package/dist/esm/components/popover/CPopover.js +47 -40
  51. package/dist/esm/components/popover/CPopover.js.map +1 -1
  52. package/dist/esm/components/tabs/CTab.d.ts +12 -0
  53. package/dist/esm/components/tabs/CTab.js +23 -0
  54. package/dist/esm/components/tabs/CTab.js.map +1 -0
  55. package/dist/esm/components/tabs/CTabList.d.ts +16 -0
  56. package/dist/esm/components/tabs/CTabList.js +52 -0
  57. package/dist/esm/components/tabs/CTabList.js.map +1 -0
  58. package/dist/esm/components/tabs/CTabPane.d.ts +6 -0
  59. package/dist/esm/components/tabs/CTabPane.js +4 -2
  60. package/dist/esm/components/tabs/CTabPane.js.map +1 -1
  61. package/dist/esm/components/tabs/CTabPanel.d.ts +28 -0
  62. package/dist/esm/components/tabs/CTabPanel.js +41 -0
  63. package/dist/esm/components/tabs/CTabPanel.js.map +1 -0
  64. package/dist/esm/components/tabs/CTabs.d.ts +22 -0
  65. package/dist/esm/components/tabs/CTabs.js +25 -0
  66. package/dist/esm/components/tabs/CTabs.js.map +1 -0
  67. package/dist/esm/components/tabs/index.d.ts +5 -1
  68. package/dist/esm/components/tooltip/CTooltip.js +50 -40
  69. package/dist/esm/components/tooltip/CTooltip.js.map +1 -1
  70. package/dist/esm/hooks/useForkedRef.d.ts +0 -1
  71. package/dist/esm/hooks/usePopper.d.ts +1 -0
  72. package/dist/esm/hooks/usePopper.js +11 -4
  73. package/dist/esm/hooks/usePopper.js.map +1 -1
  74. package/dist/esm/index.js +4 -0
  75. package/dist/esm/index.js.map +1 -1
  76. package/dist/esm/node_modules/react-transition-group/esm/CSSTransition.js +1 -2
  77. package/dist/esm/node_modules/react-transition-group/esm/CSSTransition.js.map +1 -1
  78. package/dist/esm/node_modules/react-transition-group/esm/Transition.js +1 -2
  79. package/dist/esm/node_modules/react-transition-group/esm/Transition.js.map +1 -1
  80. package/dist/esm/utils/getNextActiveElement.d.ts +2 -0
  81. package/dist/esm/utils/getNextActiveElement.js +15 -0
  82. package/dist/esm/utils/getNextActiveElement.js.map +1 -0
  83. package/dist/esm/utils/index.d.ts +2 -1
  84. package/package.json +13 -13
  85. package/src/components/button/CButton.tsx +5 -2
  86. package/src/components/button/__tests__/CButton.spec.tsx +1 -1
  87. package/src/components/button-group/__tests__/CButtonGroup.spec.tsx +6 -6
  88. package/src/components/button-group/__tests__/CButtonToolbar.spec.tsx +6 -6
  89. package/src/components/dropdown/CDropdown.tsx +2 -2
  90. package/src/components/dropdown/__tests__/CDropdownToggle.spec.tsx +1 -1
  91. package/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap +1 -1
  92. package/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.tsx.snap +1 -1
  93. package/src/components/dropdown/utils.ts +0 -22
  94. package/src/components/modal/__tests__/CModal.spec.tsx +1 -1
  95. package/src/components/nav/__tests__/__snapshots__/CNavItem.spec.tsx.snap +12 -8
  96. package/src/components/popover/CPopover.tsx +59 -66
  97. package/src/components/popover/__tests__/CPopover.spec.tsx +2 -2
  98. package/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap +22 -0
  99. package/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.tsx.snap +4 -4
  100. package/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.tsx.snap +6 -2
  101. package/src/components/tabs/CTab.tsx +56 -0
  102. package/src/components/tabs/CTabList.tsx +92 -0
  103. package/src/components/tabs/CTabPane.tsx +9 -2
  104. package/src/components/tabs/CTabPanel.tsx +98 -0
  105. package/src/components/tabs/CTabs.tsx +54 -0
  106. package/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.tsx.snap +1 -1
  107. package/src/components/tabs/index.ts +5 -1
  108. package/src/components/toast/__tests__/__snapshots__/CToaster.spec.tsx.snap +1 -1
  109. package/src/components/tooltip/CTooltip.tsx +63 -66
  110. package/src/components/tooltip/__tests__/__snapshots__/CTooltip.spec.tsx.snap +1 -0
  111. package/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.tsx.snap +1 -1
  112. package/src/hooks/usePopper.ts +15 -5
  113. package/src/utils/getNextActiveElement.ts +23 -0
  114. package/src/utils/index.ts +2 -0
@@ -18,6 +18,12 @@ export interface CTabPaneProps extends HTMLAttributes<HTMLDivElement> {
18
18
  * Callback fired when the component requests to be shown.
19
19
  */
20
20
  onShow?: () => void
21
+ /**
22
+ * Enable fade in and fade out transition.
23
+ *
24
+ * @since 5.1.0
25
+ */
26
+ transition?: boolean
21
27
  /**
22
28
  * Toggle the visibility of component.
23
29
  */
@@ -25,7 +31,7 @@ export interface CTabPaneProps extends HTMLAttributes<HTMLDivElement> {
25
31
  }
26
32
 
27
33
  export const CTabPane = forwardRef<HTMLDivElement, CTabPaneProps>(
28
- ({ children, className, onHide, onShow, visible, ...rest }, ref) => {
34
+ ({ children, className, onHide, onShow, transition = true, visible, ...rest }, ref) => {
29
35
  const tabPaneRef = useRef()
30
36
  const forkedRef = useForkedRef(ref, tabPaneRef)
31
37
 
@@ -35,9 +41,9 @@ export const CTabPane = forwardRef<HTMLDivElement, CTabPaneProps>(
35
41
  <div
36
42
  className={classNames(
37
43
  'tab-pane',
38
- 'fade',
39
44
  {
40
45
  active: visible,
46
+ fade: transition,
41
47
  show: state === 'entered',
42
48
  },
43
49
  className,
@@ -58,6 +64,7 @@ CTabPane.propTypes = {
58
64
  className: PropTypes.string,
59
65
  onHide: PropTypes.func,
60
66
  onShow: PropTypes.func,
67
+ transition: PropTypes.bool,
61
68
  visible: PropTypes.bool,
62
69
  }
63
70
 
@@ -0,0 +1,98 @@
1
+ import React, { HTMLAttributes, forwardRef, useContext, useEffect, useRef, useState } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import classNames from 'classnames'
4
+ import { Transition } from 'react-transition-group'
5
+
6
+ import { TabsContext } from './CTabs'
7
+ import { useForkedRef } from '../../hooks'
8
+ import { getTransitionDurationFromElement } from '../../utils'
9
+
10
+ export interface CTabPanelProps extends HTMLAttributes<HTMLDivElement> {
11
+ /**
12
+ * A string of all className you want applied to the base component.
13
+ */
14
+ className?: string
15
+ /**
16
+ * Item key.
17
+ */
18
+ itemKey: number | string
19
+ /**
20
+ * Callback fired when the component requests to be hidden.
21
+ */
22
+ onHide?: () => void
23
+ /**
24
+ * Callback fired when the component requests to be shown.
25
+ */
26
+ onShow?: () => void
27
+ /**
28
+ * Enable fade in and fade out transition.
29
+ */
30
+ transition?: boolean
31
+ /**
32
+ * Toggle the visibility of component.
33
+ */
34
+ visible?: boolean
35
+ }
36
+
37
+ export const CTabPanel = forwardRef<HTMLDivElement, CTabPanelProps>(
38
+ ({ children, className, itemKey, onHide, onShow, transition = true, visible, ...rest }, ref) => {
39
+ const { _activeItemKey, id } = useContext(TabsContext)
40
+
41
+ const tabPaneRef = useRef()
42
+ const forkedRef = useForkedRef(ref, tabPaneRef)
43
+
44
+ const [_visible, setVisible] = useState(visible || _activeItemKey === itemKey)
45
+
46
+ useEffect(() => {
47
+ visible !== undefined && setVisible(visible)
48
+ }, [visible])
49
+
50
+ useEffect(() => {
51
+ setVisible(_activeItemKey === itemKey)
52
+ }, [_activeItemKey])
53
+
54
+ return (
55
+ <Transition
56
+ in={_visible}
57
+ nodeRef={tabPaneRef}
58
+ onEnter={onShow}
59
+ onExit={onHide}
60
+ timeout={tabPaneRef.current ? getTransitionDurationFromElement(tabPaneRef.current) : 0}
61
+ >
62
+ {(state) => (
63
+ <div
64
+ className={classNames(
65
+ 'tab-pane',
66
+ {
67
+ active: _visible,
68
+ fade: transition,
69
+ show: state === 'entered',
70
+ },
71
+ className,
72
+ )}
73
+ id={`${id}${itemKey}-tab-pane`}
74
+ role="tabpanel"
75
+ aria-labelledby={`${id}${itemKey}-tab`}
76
+ tabIndex={0}
77
+ ref={forkedRef}
78
+ {...rest}
79
+ >
80
+ {children}
81
+ </div>
82
+ )}
83
+ </Transition>
84
+ )
85
+ },
86
+ )
87
+
88
+ CTabPanel.propTypes = {
89
+ children: PropTypes.node,
90
+ className: PropTypes.string,
91
+ itemKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
92
+ onHide: PropTypes.func,
93
+ onShow: PropTypes.func,
94
+ transition: PropTypes.bool,
95
+ visible: PropTypes.bool,
96
+ }
97
+
98
+ CTabPanel.displayName = 'CTabPanel'
@@ -0,0 +1,54 @@
1
+ import React, { createContext, forwardRef, HTMLAttributes, useEffect, useId, useState } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import classNames from 'classnames'
4
+
5
+ export interface CTabsProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
6
+ /**
7
+ * The active item key.
8
+ */
9
+ activeItemKey: number | string
10
+ /**
11
+ * A string of all className you want applied to the base component.
12
+ */
13
+ className?: string
14
+ /**
15
+ * The callback is fired when the active tab changes.
16
+ */
17
+ onChange?: (value: number | string) => void
18
+ }
19
+
20
+ export interface TabsContextProps {
21
+ _activeItemKey?: number | string
22
+ setActiveItemKey: React.Dispatch<React.SetStateAction<number | string | undefined>>
23
+ id?: string
24
+ }
25
+
26
+ export const TabsContext = createContext({} as TabsContextProps)
27
+
28
+ export const CTabs = forwardRef<HTMLDivElement, CTabsProps>(
29
+ ({ children, activeItemKey, className, onChange }, ref) => {
30
+ const id = useId()
31
+ const [_activeItemKey, setActiveItemKey] = useState(activeItemKey)
32
+
33
+ useEffect(() => {
34
+ _activeItemKey && onChange && onChange(_activeItemKey)
35
+ }, [_activeItemKey])
36
+
37
+ return (
38
+ <TabsContext.Provider value={{ _activeItemKey, setActiveItemKey, id }}>
39
+ <div className={classNames('tabs', className)} ref={ref}>
40
+ {children}
41
+ </div>
42
+ </TabsContext.Provider>
43
+ )
44
+ },
45
+ )
46
+
47
+ CTabs.propTypes = {
48
+ activeItemKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
49
+ children: PropTypes.node,
50
+ className: PropTypes.string,
51
+ onChange: PropTypes.func,
52
+ }
53
+
54
+ CTabs.displayName = 'CTabs'
@@ -3,7 +3,7 @@
3
3
  exports[`CTabPane customize 1`] = `
4
4
  <div>
5
5
  <div
6
- class="tab-pane fade active show bazinga"
6
+ class="tab-pane active fade show bazinga"
7
7
  >
8
8
  Test
9
9
  </div>
@@ -1,4 +1,8 @@
1
+ import { CTab } from './CTab'
1
2
  import { CTabContent } from './CTabContent'
2
3
  import { CTabPane } from './CTabPane'
4
+ import { CTabPanel } from './CTabPanel'
5
+ import { CTabList } from './CTabList'
6
+ import { CTabs } from './CTabs'
3
7
 
4
- export { CTabContent, CTabPane }
8
+ export { CTab, CTabContent, CTabList, CTabPane, CTabPanel, CTabs }
@@ -6,7 +6,7 @@ exports[`CToaster customize 1`] = `
6
6
  class="toaster toast-container bazinga"
7
7
  />
8
8
  <button
9
- class="btn btn-primary"
9
+ class="btn"
10
10
  type="button"
11
11
  >
12
12
  Send a toast
@@ -1,13 +1,12 @@
1
1
  import React, { forwardRef, HTMLAttributes, ReactNode, useRef, useEffect, useState } from 'react'
2
2
  import classNames from 'classnames'
3
3
  import PropTypes from 'prop-types'
4
- import { Transition } from 'react-transition-group'
5
4
 
6
5
  import { CConditionalPortal } from '../conditional-portal'
7
6
  import { useForkedRef, usePopper } from '../../hooks'
8
7
  import { fallbackPlacementsPropType, triggerPropType } from '../../props'
9
8
  import type { Placements, Triggers } from '../../types'
10
- import { getRTLPlacement, getTransitionDurationFromElement } from '../../utils'
9
+ import { executeAfterTransition, getRTLPlacement } from '../../utils'
11
10
 
12
11
  export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {
13
12
  /**
@@ -95,7 +94,8 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
95
94
  const forkedRef = useForkedRef(ref, tooltipRef)
96
95
  const uID = useRef(`tooltip${Math.floor(Math.random() * 1_000_000)}`)
97
96
 
98
- const { initPopper, destroyPopper } = usePopper()
97
+ const { initPopper, destroyPopper, updatePopper } = usePopper()
98
+ const [mounted, setMounted] = useState(false)
99
99
  const [_visible, setVisible] = useState(visible)
100
100
 
101
101
  const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay
@@ -128,14 +128,48 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
128
128
  setVisible(visible)
129
129
  }, [visible])
130
130
 
131
- const toggleVisible = (visible: boolean) => {
132
- if (visible) {
133
- setTimeout(() => setVisible(true), _delay.show)
134
- return
131
+ useEffect(() => {
132
+ if (_visible) {
133
+ setMounted(true)
134
+
135
+ if (tooltipRef.current) {
136
+ tooltipRef.current.classList.remove('fade', 'show')
137
+ destroyPopper()
138
+ }
139
+
140
+ setTimeout(() => {
141
+ if (togglerRef.current && tooltipRef.current) {
142
+ if (animation) {
143
+ tooltipRef.current.classList.add('fade')
144
+ }
145
+
146
+ initPopper(togglerRef.current, tooltipRef.current, popperConfig)
147
+ tooltipRef.current.style.removeProperty('display')
148
+ tooltipRef.current.classList.add('show')
149
+ onShow && onShow()
150
+ }
151
+ }, _delay.show)
135
152
  }
136
153
 
137
- setTimeout(() => setVisible(false), _delay.hide)
138
- }
154
+ return () => {
155
+ if (tooltipRef.current) {
156
+ tooltipRef.current.classList.remove('show')
157
+ onHide && onHide()
158
+ executeAfterTransition(() => {
159
+ if (tooltipRef.current) {
160
+ tooltipRef.current.style.display = 'none'
161
+ }
162
+
163
+ destroyPopper()
164
+ setMounted(false)
165
+ }, tooltipRef.current)
166
+ }
167
+ }
168
+ }, [_visible])
169
+
170
+ useEffect(() => {
171
+ updatePopper()
172
+ }, [content])
139
173
 
140
174
  return (
141
175
  <>
@@ -145,70 +179,33 @@ export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>(
145
179
  }),
146
180
  ref: togglerRef,
147
181
  ...((trigger === 'click' || trigger.includes('click')) && {
148
- onClick: () => toggleVisible(!_visible),
182
+ onClick: () => setVisible(!_visible),
149
183
  }),
150
184
  ...((trigger === 'focus' || trigger.includes('focus')) && {
151
- onFocus: () => toggleVisible(true),
152
- onBlur: () => toggleVisible(false),
185
+ onFocus: () => setVisible(true),
186
+ onBlur: () => setVisible(false),
153
187
  }),
154
188
  ...((trigger === 'hover' || trigger.includes('hover')) && {
155
- onMouseEnter: () => toggleVisible(true),
156
- onMouseLeave: () => toggleVisible(false),
189
+ onMouseEnter: () => setVisible(true),
190
+ onMouseLeave: () => setVisible(false),
157
191
  }),
158
192
  })}
159
193
  <CConditionalPortal container={container} portal={true}>
160
- <Transition
161
- in={_visible}
162
- mountOnEnter
163
- nodeRef={tooltipRef}
164
- onEnter={() => {
165
- if (togglerRef.current && tooltipRef.current) {
166
- initPopper(togglerRef.current, tooltipRef.current, popperConfig)
167
- }
168
-
169
- onShow
170
- }}
171
- onEntering={() => {
172
- if (togglerRef.current && tooltipRef.current) {
173
- tooltipRef.current.style.display = 'initial'
174
- }
175
- }}
176
- onExit={onHide}
177
- onExited={() => {
178
- destroyPopper()
179
- }}
180
- timeout={{
181
- enter: 0,
182
- exit: tooltipRef.current
183
- ? getTransitionDurationFromElement(tooltipRef.current) + 50
184
- : 200,
185
- }}
186
- unmountOnExit
187
- >
188
- {(state) => (
189
- <div
190
- className={classNames(
191
- 'tooltip',
192
- 'bs-tooltip-auto',
193
- {
194
- fade: animation,
195
- show: state === 'entered',
196
- },
197
- className,
198
- )}
199
- id={uID.current}
200
- ref={forkedRef}
201
- role="tooltip"
202
- style={{
203
- display: 'none',
204
- }}
205
- {...rest}
206
- >
207
- <div className="tooltip-arrow"></div>
208
- <div className="tooltip-inner">{content}</div>
209
- </div>
210
- )}
211
- </Transition>
194
+ {mounted && (
195
+ <div
196
+ className={classNames('tooltip', 'bs-tooltip-auto', className)}
197
+ id={uID.current}
198
+ ref={forkedRef}
199
+ role="tooltip"
200
+ style={{
201
+ display: 'none',
202
+ }}
203
+ {...rest}
204
+ >
205
+ <div className="tooltip-arrow"></div>
206
+ <div className="tooltip-inner">{content}</div>
207
+ </div>
208
+ )}
212
209
  </CConditionalPortal>
213
210
  </>
214
211
  )
@@ -3,6 +3,7 @@
3
3
  exports[`CTooltip customize 1`] = `
4
4
  <div>
5
5
  <a
6
+ aria-describedby="tooltip97108"
6
7
  class="link"
7
8
  >
8
9
  Test
@@ -9,7 +9,7 @@ exports[`CWidgetStatsC customize 1`] = `
9
9
  class="card-body"
10
10
  >
11
11
  <div
12
- class="text-end mb-4"
12
+ class="text-end mb-4 text-white text-opacity-75"
13
13
  >
14
14
  icon
15
15
  </div>
@@ -2,12 +2,11 @@ import { useRef } from 'react'
2
2
  import { createPopper } from '@popperjs/core'
3
3
  import type { Instance, Options } from '@popperjs/core'
4
4
 
5
- import { executeAfterTransition } from '../utils'
6
-
7
5
  interface UsePopperOutput {
8
6
  popper: Instance | undefined
9
7
  initPopper: (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => void
10
8
  destroyPopper: () => void
9
+ updatePopper: (options?: Partial<Options>) => void
11
10
  }
12
11
 
13
12
  export const usePopper = (): UsePopperOutput => {
@@ -23,17 +22,28 @@ export const usePopper = (): UsePopperOutput => {
23
22
  const popperInstance = _popper.current
24
23
 
25
24
  if (popperInstance && el.current) {
26
- executeAfterTransition(() => {
27
- popperInstance.destroy()
28
- }, el.current)
25
+ popperInstance.destroy()
29
26
  }
30
27
 
31
28
  _popper.current = undefined
32
29
  }
33
30
 
31
+ const updatePopper = (options?: Partial<Options>) => {
32
+ const popperInstance = _popper.current
33
+
34
+ if (popperInstance && options) {
35
+ popperInstance.setOptions(options)
36
+ }
37
+
38
+ if (popperInstance) {
39
+ popperInstance.update()
40
+ }
41
+ }
42
+
34
43
  return {
35
44
  popper: _popper.current,
36
45
  initPopper,
37
46
  destroyPopper,
47
+ updatePopper,
38
48
  }
39
49
  }
@@ -0,0 +1,23 @@
1
+ const getNextActiveElement = (
2
+ list: HTMLElement[],
3
+ activeElement: HTMLElement,
4
+ shouldGetNext: boolean,
5
+ isCycleAllowed: boolean,
6
+ ) => {
7
+ const listLength = list.length
8
+ let index = list.indexOf(activeElement)
9
+
10
+ if (index === -1) {
11
+ return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]
12
+ }
13
+
14
+ index += shouldGetNext ? 1 : -1
15
+
16
+ if (isCycleAllowed) {
17
+ index = (index + listLength) % listLength
18
+ }
19
+
20
+ return list[Math.max(0, Math.min(index, listLength - 1))]
21
+ }
22
+
23
+ export default getNextActiveElement
@@ -1,4 +1,5 @@
1
1
  import executeAfterTransition from './executeAfterTransition'
2
+ import getNextActiveElement from './getNextActiveElement'
2
3
  import getRTLPlacement from './getRTLPlacement'
3
4
  import getTransitionDurationFromElement from './getTransitionDurationFromElement'
4
5
  import isInViewport from './isInViewport'
@@ -6,6 +7,7 @@ import isRTL from './isRTL'
6
7
 
7
8
  export {
8
9
  executeAfterTransition,
10
+ getNextActiveElement,
9
11
  getRTLPlacement,
10
12
  getTransitionDurationFromElement,
11
13
  isInViewport,