@coreui/react-pro 4.12.0-beta.1 → 4.12.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/components/dropdown/CDropdown.d.ts +8 -1
- package/dist/components/dropdown/CDropdownMenu.d.ts +3 -4
- package/dist/components/multi-select/CMultiSelect.d.ts +2 -2
- package/dist/components/popover/CPopover.d.ts +22 -1
- package/dist/components/progress/CProgress.d.ts +6 -0
- package/dist/components/progress/CProgressStacked.d.ts +12 -0
- package/dist/components/progress/index.d.ts +2 -1
- package/dist/components/tooltip/CTooltip.d.ts +22 -1
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/useColorModes.d.ts +3 -2
- package/dist/hooks/usePopper.d.ts +8 -0
- package/dist/index.es.js +6682 -7089
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +6300 -6723
- package/dist/index.js.map +1 -1
- package/dist/props.d.ts +1 -0
- package/dist/utils/getRTLPlacement.d.ts +3 -0
- package/dist/utils/index.d.ts +2 -1
- package/package.json +5 -5
- package/src/components/date-range-picker/CDateRangePicker.tsx +10 -7
- package/src/components/dropdown/CDropdown.tsx +130 -45
- package/src/components/dropdown/CDropdownMenu.tsx +41 -138
- package/src/components/dropdown/CDropdownToggle.tsx +6 -15
- package/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap +0 -1
- package/src/components/multi-select/CMultiSelect.tsx +30 -39
- package/src/components/picker/CPicker.tsx +24 -34
- package/src/components/popover/CPopover.tsx +76 -51
- package/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap +0 -21
- package/src/components/progress/CProgress.tsx +43 -8
- package/src/components/progress/CProgressBar.tsx +5 -6
- package/src/components/progress/CProgressStacked.tsx +39 -0
- package/src/components/progress/index.ts +2 -1
- package/src/components/tooltip/CTooltip.tsx +77 -52
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useColorModes.ts +21 -11
- package/src/hooks/usePopper.ts +31 -0
- package/src/props.ts +5 -0
- package/src/utils/getRTLPlacement.ts +18 -0
- package/src/utils/index.ts +2 -1
|
@@ -3,13 +3,19 @@ import { createPortal } from 'react-dom'
|
|
|
3
3
|
import classNames from 'classnames'
|
|
4
4
|
import PropTypes from 'prop-types'
|
|
5
5
|
import { Transition } from 'react-transition-group'
|
|
6
|
-
import { createPopper, Instance, Placement } from '@popperjs/core'
|
|
7
6
|
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
7
|
+
import { usePopper } from '../../hooks'
|
|
8
|
+
import { fallbackPlacementsPropType, triggerPropType } from '../../props'
|
|
9
|
+
import type { Placements, Triggers } from '../../types'
|
|
10
|
+
import { getRTLPlacement } from '../../utils'
|
|
11
11
|
|
|
12
12
|
export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {
|
|
13
|
+
/**
|
|
14
|
+
* Apply a CSS fade transition to the tooltip.
|
|
15
|
+
*
|
|
16
|
+
* @since 4.9.0-beta.1
|
|
17
|
+
*/
|
|
18
|
+
animation?: boolean
|
|
13
19
|
/**
|
|
14
20
|
* A string of all className you want applied to the component.
|
|
15
21
|
*/
|
|
@@ -18,6 +24,18 @@ export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'con
|
|
|
18
24
|
* Content node for your component.
|
|
19
25
|
*/
|
|
20
26
|
content: ReactNode | string
|
|
27
|
+
/**
|
|
28
|
+
* The delay for displaying and hiding the tooltip (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`.
|
|
29
|
+
*
|
|
30
|
+
* @since 4.9.0-beta.1
|
|
31
|
+
*/
|
|
32
|
+
delay?: number | { show: number; hide: number }
|
|
33
|
+
/**
|
|
34
|
+
* Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference.
|
|
35
|
+
*
|
|
36
|
+
* @since 4.9.0-beta.1
|
|
37
|
+
*/
|
|
38
|
+
fallbackPlacements?: Placements | Placements[]
|
|
21
39
|
/**
|
|
22
40
|
* Offset of the tooltip relative to its target.
|
|
23
41
|
*/
|
|
@@ -46,44 +64,59 @@ export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'con
|
|
|
46
64
|
visible?: boolean
|
|
47
65
|
}
|
|
48
66
|
|
|
49
|
-
const getPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
|
|
50
|
-
switch (placement) {
|
|
51
|
-
case 'right': {
|
|
52
|
-
return isRTL(element) ? 'left' : 'right'
|
|
53
|
-
}
|
|
54
|
-
case 'left': {
|
|
55
|
-
return isRTL(element) ? 'right' : 'left'
|
|
56
|
-
}
|
|
57
|
-
default: {
|
|
58
|
-
return placement as Placement
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
67
|
export const CTooltip: FC<CTooltipProps> = ({
|
|
64
68
|
children,
|
|
69
|
+
animation = true,
|
|
65
70
|
className,
|
|
66
71
|
content,
|
|
72
|
+
delay = 0,
|
|
73
|
+
fallbackPlacements = ['top', 'right', 'bottom', 'left'],
|
|
67
74
|
offset = [0, 6],
|
|
68
75
|
onHide,
|
|
69
76
|
onShow,
|
|
70
77
|
placement = 'top',
|
|
71
|
-
trigger = 'hover',
|
|
78
|
+
trigger = ['hover', 'focus'],
|
|
72
79
|
visible,
|
|
73
80
|
...rest
|
|
74
81
|
}) => {
|
|
75
82
|
const tooltipRef = useRef(null)
|
|
76
83
|
const togglerRef = useRef(null)
|
|
77
|
-
const
|
|
84
|
+
const { initPopper, destroyPopper } = usePopper()
|
|
78
85
|
const [_visible, setVisible] = useState(visible)
|
|
79
86
|
|
|
87
|
+
const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay
|
|
88
|
+
|
|
89
|
+
const popperConfig = {
|
|
90
|
+
modifiers: [
|
|
91
|
+
{
|
|
92
|
+
name: 'arrow',
|
|
93
|
+
options: {
|
|
94
|
+
element: '.tooltip-arrow',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'flip',
|
|
99
|
+
options: {
|
|
100
|
+
fallbackPlacements: fallbackPlacements,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'offset',
|
|
105
|
+
options: {
|
|
106
|
+
offset: offset,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
placement: getRTLPlacement(placement, togglerRef.current),
|
|
111
|
+
}
|
|
112
|
+
|
|
80
113
|
useEffect(() => {
|
|
81
114
|
setVisible(visible)
|
|
82
115
|
}, [visible])
|
|
83
116
|
|
|
84
117
|
useEffect(() => {
|
|
85
|
-
if (_visible) {
|
|
86
|
-
initPopper()
|
|
118
|
+
if (_visible && togglerRef.current && tooltipRef.current) {
|
|
119
|
+
initPopper(togglerRef.current, tooltipRef.current, popperConfig)
|
|
87
120
|
}
|
|
88
121
|
|
|
89
122
|
return () => {
|
|
@@ -91,28 +124,13 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
91
124
|
}
|
|
92
125
|
}, [_visible])
|
|
93
126
|
|
|
94
|
-
const
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
{
|
|
99
|
-
name: 'offset',
|
|
100
|
-
options: {
|
|
101
|
-
offset: offset,
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
],
|
|
105
|
-
placement: getPlacement(placement, togglerRef.current),
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const destroyPopper = () => {
|
|
111
|
-
if (popper.current) {
|
|
112
|
-
popper.current.destroy()
|
|
127
|
+
const toggleVisible = (visible: boolean) => {
|
|
128
|
+
if (visible) {
|
|
129
|
+
setTimeout(() => setVisible(true), _delay.show)
|
|
130
|
+
return
|
|
113
131
|
}
|
|
114
132
|
|
|
115
|
-
|
|
133
|
+
setTimeout(() => setVisible(false), _delay.hide)
|
|
116
134
|
}
|
|
117
135
|
|
|
118
136
|
return (
|
|
@@ -120,15 +138,15 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
120
138
|
{React.cloneElement(children as React.ReactElement<any>, {
|
|
121
139
|
ref: togglerRef,
|
|
122
140
|
...((trigger === 'click' || trigger.includes('click')) && {
|
|
123
|
-
onClick: () =>
|
|
141
|
+
onClick: () => toggleVisible(!_visible),
|
|
124
142
|
}),
|
|
125
143
|
...((trigger === 'focus' || trigger.includes('focus')) && {
|
|
126
|
-
onFocus: () =>
|
|
127
|
-
onBlur: () =>
|
|
144
|
+
onFocus: () => toggleVisible(true),
|
|
145
|
+
onBlur: () => toggleVisible(false),
|
|
128
146
|
}),
|
|
129
147
|
...((trigger === 'hover' || trigger.includes('hover')) && {
|
|
130
|
-
onMouseEnter: () =>
|
|
131
|
-
onMouseLeave: () =>
|
|
148
|
+
onMouseEnter: () => toggleVisible(true),
|
|
149
|
+
onMouseLeave: () => toggleVisible(false),
|
|
132
150
|
}),
|
|
133
151
|
})}
|
|
134
152
|
{typeof window !== 'undefined' &&
|
|
@@ -148,11 +166,9 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
148
166
|
<div
|
|
149
167
|
className={classNames(
|
|
150
168
|
'tooltip',
|
|
151
|
-
|
|
152
|
-
.replace('left', 'start')
|
|
153
|
-
.replace('right', 'end')}`,
|
|
154
|
-
'fade',
|
|
169
|
+
'bs-tooltip-auto',
|
|
155
170
|
{
|
|
171
|
+
fade: animation,
|
|
156
172
|
show: state === 'entered',
|
|
157
173
|
},
|
|
158
174
|
className,
|
|
@@ -161,7 +177,7 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
161
177
|
role="tooltip"
|
|
162
178
|
{...rest}
|
|
163
179
|
>
|
|
164
|
-
<div
|
|
180
|
+
<div className="tooltip-arrow"></div>
|
|
165
181
|
<div className="tooltip-inner">{content}</div>
|
|
166
182
|
</div>
|
|
167
183
|
)}
|
|
@@ -173,8 +189,17 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
173
189
|
}
|
|
174
190
|
|
|
175
191
|
CTooltip.propTypes = {
|
|
192
|
+
animation: PropTypes.bool,
|
|
176
193
|
children: PropTypes.node,
|
|
177
194
|
content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
195
|
+
delay: PropTypes.oneOfType([
|
|
196
|
+
PropTypes.number,
|
|
197
|
+
PropTypes.shape({
|
|
198
|
+
show: PropTypes.number.isRequired,
|
|
199
|
+
hide: PropTypes.number.isRequired,
|
|
200
|
+
}),
|
|
201
|
+
]),
|
|
202
|
+
fallbackPlacements: fallbackPlacementsPropType,
|
|
178
203
|
offset: PropTypes.any, // TODO: find good proptype
|
|
179
204
|
onHide: PropTypes.func,
|
|
180
205
|
onShow: PropTypes.func,
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useColorModes } from './useColorModes'
|
|
2
2
|
import { useForkedRef } from './useForkedRef'
|
|
3
|
+
import { usePopper } from './usePopper'
|
|
3
4
|
import { useStateWithCallback } from './useStateWithCallback'
|
|
4
5
|
|
|
5
|
-
export { useColorModes, useForkedRef, useStateWithCallback }
|
|
6
|
+
export { useColorModes, useForkedRef, usePopper, useStateWithCallback }
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react'
|
|
1
|
+
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
interface UseColorModesOutput {
|
|
4
|
-
|
|
4
|
+
colorMode: string | undefined
|
|
5
5
|
isColorModeSet: () => boolean
|
|
6
|
-
setColorMode:
|
|
6
|
+
setColorMode: Dispatch<SetStateAction<string>>
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const getStoredTheme = (localStorageItemName: string) =>
|
|
9
|
+
const getStoredTheme = (localStorageItemName: string) =>
|
|
10
|
+
typeof window !== 'undefined' && localStorage.getItem(localStorageItemName)
|
|
11
|
+
|
|
10
12
|
const setStoredTheme = (localStorageItemName: string, colorMode: string) =>
|
|
11
13
|
localStorage.setItem(localStorageItemName, colorMode)
|
|
12
14
|
|
|
13
15
|
const getPreferredColorScheme = (localStorageItemName: string) => {
|
|
16
|
+
if (typeof window === 'undefined') {
|
|
17
|
+
return 'light'
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
const storedTheme = getStoredTheme(localStorageItemName)
|
|
15
21
|
|
|
16
22
|
if (storedTheme) {
|
|
@@ -33,25 +39,29 @@ const setTheme = (colorMode: string) => {
|
|
|
33
39
|
export const useColorModes = (
|
|
34
40
|
localStorageItemName = 'coreui-react-color-scheme',
|
|
35
41
|
): UseColorModesOutput => {
|
|
36
|
-
const [colorMode, setColorMode] = useState<string>(
|
|
42
|
+
const [colorMode, setColorMode] = useState<string | undefined>(
|
|
43
|
+
getPreferredColorScheme(localStorageItemName),
|
|
44
|
+
)
|
|
37
45
|
|
|
38
46
|
useEffect(() => {
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
if (colorMode) {
|
|
48
|
+
setStoredTheme(localStorageItemName, colorMode)
|
|
49
|
+
setTheme(colorMode)
|
|
50
|
+
}
|
|
41
51
|
}, [colorMode])
|
|
42
52
|
|
|
43
53
|
useEffect(() => {
|
|
44
54
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
|
45
55
|
const storedTheme = getStoredTheme(localStorageItemName)
|
|
46
|
-
if (storedTheme !== 'light' && storedTheme !== 'dark') {
|
|
56
|
+
if (storedTheme !== 'light' && storedTheme !== 'dark' && colorMode) {
|
|
47
57
|
setTheme(colorMode)
|
|
48
58
|
}
|
|
49
59
|
})
|
|
50
|
-
}
|
|
60
|
+
})
|
|
51
61
|
|
|
52
62
|
return {
|
|
53
|
-
|
|
63
|
+
colorMode,
|
|
54
64
|
isColorModeSet: () => Boolean(getStoredTheme(localStorageItemName)),
|
|
55
|
-
setColorMode
|
|
65
|
+
setColorMode,
|
|
56
66
|
}
|
|
57
67
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useRef } from 'react'
|
|
2
|
+
import { createPopper } from '@popperjs/core'
|
|
3
|
+
import type { Instance, Options } from '@popperjs/core'
|
|
4
|
+
|
|
5
|
+
interface UsePopperOutput {
|
|
6
|
+
popper: Instance | undefined
|
|
7
|
+
initPopper: (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => void
|
|
8
|
+
destroyPopper: () => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const usePopper = (): UsePopperOutput => {
|
|
12
|
+
const _popper = useRef<Instance>()
|
|
13
|
+
|
|
14
|
+
const initPopper = (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => {
|
|
15
|
+
_popper.current = createPopper(reference, popper, options)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const destroyPopper = () => {
|
|
19
|
+
if (_popper.current) {
|
|
20
|
+
_popper.current.destroy()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
_popper.current = undefined
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
popper: _popper.current,
|
|
28
|
+
initPopper,
|
|
29
|
+
destroyPopper,
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/props.ts
CHANGED
|
@@ -16,6 +16,11 @@ export const colorPropType = PropTypes.oneOfType([
|
|
|
16
16
|
PropTypes.string,
|
|
17
17
|
])
|
|
18
18
|
|
|
19
|
+
export const fallbackPlacementsPropType = PropTypes.oneOfType([
|
|
20
|
+
PropTypes.arrayOf(PropTypes.oneOf<Placements>(['top', 'bottom', 'right', 'left']).isRequired),
|
|
21
|
+
PropTypes.oneOf<Placements>(['top', 'bottom', 'right', 'left']),
|
|
22
|
+
])
|
|
23
|
+
|
|
19
24
|
export const gradientsPropType = PropTypes.oneOf([
|
|
20
25
|
'primary-gradient',
|
|
21
26
|
'secondary-gradient',
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Placement } from '@popperjs/core'
|
|
2
|
+
import { isRTL } from '../utils'
|
|
3
|
+
|
|
4
|
+
const getRTLPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
|
|
5
|
+
switch (placement) {
|
|
6
|
+
case 'right': {
|
|
7
|
+
return isRTL(element) ? 'left' : 'right'
|
|
8
|
+
}
|
|
9
|
+
case 'left': {
|
|
10
|
+
return isRTL(element) ? 'right' : 'left'
|
|
11
|
+
}
|
|
12
|
+
default: {
|
|
13
|
+
return placement as Placement
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default getRTLPlacement
|
package/src/utils/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import getRTLPlacement from './getRTLPlacement'
|
|
1
2
|
import isInViewport from './isInViewport'
|
|
2
3
|
import isObjectInArray from './isObjectInArray'
|
|
3
4
|
import isRTL from './isRTL'
|
|
4
5
|
|
|
5
|
-
export { isInViewport, isObjectInArray, isRTL }
|
|
6
|
+
export { getRTLPlacement, isInViewport, isObjectInArray, isRTL }
|