@coreui/react 4.8.0 → 4.9.0-alpha.1
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/popover/CPopover.d.ts +1 -1
- package/dist/components/tooltip/CTooltip.d.ts +3 -3
- package/dist/index.es.js +739 -665
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +739 -665
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/isRTL.d.ts +2 -0
- package/package.json +11 -10
- package/src/components/dropdown/CDropdownMenu.tsx +5 -4
- package/src/components/form/CFormCheck.tsx +1 -1
- package/src/components/popover/CPopover.tsx +62 -26
- package/src/components/tooltip/CTooltip.tsx +66 -31
- package/src/utils/index.ts +2 -1
- package/src/utils/isRTL.ts +13 -0
package/dist/utils/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreui/react",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.0-alpha.1",
|
|
4
4
|
"description": "UI Components Library for React.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -37,15 +37,15 @@
|
|
|
37
37
|
"test:update": "jest --coverage --updateSnapshot"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@popperjs/core": "^2.11.
|
|
41
|
-
"@rollup/plugin-commonjs": "^24.0
|
|
42
|
-
"@rollup/plugin-node-resolve": "^15.0.
|
|
43
|
-
"@rollup/plugin-typescript": "^11.
|
|
40
|
+
"@popperjs/core": "^2.11.7",
|
|
41
|
+
"@rollup/plugin-commonjs": "^24.1.0",
|
|
42
|
+
"@rollup/plugin-node-resolve": "^15.0.2",
|
|
43
|
+
"@rollup/plugin-typescript": "^11.1.0",
|
|
44
44
|
"@testing-library/jest-dom": "^5.16.5",
|
|
45
45
|
"@testing-library/react": "^14.0.0",
|
|
46
|
-
"@types/react": "18.
|
|
47
|
-
"@types/react-dom": "^18.
|
|
48
|
-
"@types/react-transition-group": "^4.4.
|
|
46
|
+
"@types/react": "18.2.6",
|
|
47
|
+
"@types/react-dom": "^18.2.4",
|
|
48
|
+
"@types/react-transition-group": "^4.4.6",
|
|
49
49
|
"classnames": "^2.3.2",
|
|
50
50
|
"jest": "^29.5.0",
|
|
51
51
|
"jest-environment-jsdom": "^29.5.0",
|
|
@@ -54,12 +54,13 @@
|
|
|
54
54
|
"react-dom": "^18.2.0",
|
|
55
55
|
"react-popper": "^2.3.0",
|
|
56
56
|
"react-transition-group": "^4.4.5",
|
|
57
|
-
"rollup": "^3.
|
|
57
|
+
"rollup": "^3.21.6",
|
|
58
58
|
"tslib": "^2.5.0",
|
|
59
|
-
"ts-jest": "^29.0
|
|
59
|
+
"ts-jest": "^29.1.0",
|
|
60
60
|
"typescript": "^4.9.5"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
|
+
"@coreui/coreui": "4.3.0-alpha.0",
|
|
63
64
|
"react": ">=17",
|
|
64
65
|
"react-dom": ">=17"
|
|
65
66
|
}
|
|
@@ -7,6 +7,7 @@ import { Alignments, CDropdownContext } from './CDropdown'
|
|
|
7
7
|
import { CConditionalPortal } from '../conditional-portal'
|
|
8
8
|
|
|
9
9
|
import type { Placements } from '../../types'
|
|
10
|
+
import { isRTL } from '../../utils'
|
|
10
11
|
|
|
11
12
|
export interface CDropdownMenuProps
|
|
12
13
|
extends HTMLAttributes<HTMLDivElement | HTMLUListElement>,
|
|
@@ -109,7 +110,7 @@ export const CDropdownMenu: FC<CDropdownMenuProps> = ({
|
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
if (direction === 'dropup') {
|
|
112
|
-
_placement = 'top-start'
|
|
113
|
+
_placement = isRTL(dropdownMenuRef.current) ? 'top-end' : 'top-start'
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
if (direction === 'dropup-center') {
|
|
@@ -117,15 +118,15 @@ export const CDropdownMenu: FC<CDropdownMenuProps> = ({
|
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
if (direction === 'dropend') {
|
|
120
|
-
_placement = 'right-start'
|
|
121
|
+
_placement = isRTL(dropdownMenuRef.current) ? 'left-start' : 'right-start'
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
if (direction === 'dropstart') {
|
|
124
|
-
_placement = 'left-start'
|
|
125
|
+
_placement = isRTL(dropdownMenuRef.current) ? 'right-start' : 'left-start'
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
if (alignment === 'end') {
|
|
128
|
-
_placement = 'bottom-end'
|
|
129
|
+
_placement = isRTL(dropdownMenuRef.current) ? 'bottom-start' : 'bottom-end'
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
const dropdownMenuComponent = (style?: React.CSSProperties, ref?: React.Ref<HTMLDivElement>) => (
|
|
@@ -112,7 +112,7 @@ export const CFormCheck = forwardRef<HTMLInputElement, CFormCheckProps>(
|
|
|
112
112
|
if (inputRef.current && indeterminate) {
|
|
113
113
|
inputRef.current.indeterminate = indeterminate
|
|
114
114
|
}
|
|
115
|
-
}, [indeterminate])
|
|
115
|
+
}, [indeterminate, inputRef.current])
|
|
116
116
|
|
|
117
117
|
const FormControl = () => (
|
|
118
118
|
<input
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import React, { FC, HTMLAttributes, ReactNode, useRef, useEffect, useState } from 'react'
|
|
2
2
|
import { createPortal } from 'react-dom'
|
|
3
|
-
import PropTypes from 'prop-types'
|
|
4
3
|
import classNames from 'classnames'
|
|
5
|
-
import
|
|
4
|
+
import PropTypes from 'prop-types'
|
|
6
5
|
import { Transition } from 'react-transition-group'
|
|
6
|
+
import { createPopper, Instance, Placement } from '@popperjs/core'
|
|
7
7
|
|
|
8
8
|
import { triggerPropType } from '../../props'
|
|
9
9
|
import type { Triggers } from '../../types'
|
|
10
|
+
import { isRTL } from '../../utils'
|
|
10
11
|
|
|
11
|
-
export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
12
|
+
export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'content'> {
|
|
12
13
|
/**
|
|
13
14
|
* A string of all className you want applied to the component.
|
|
14
15
|
*/
|
|
@@ -49,6 +50,21 @@ export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'tit
|
|
|
49
50
|
visible?: boolean
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
const getPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
|
|
54
|
+
console.log(element)
|
|
55
|
+
switch (placement) {
|
|
56
|
+
case 'right': {
|
|
57
|
+
return isRTL(element) ? 'left' : 'right'
|
|
58
|
+
}
|
|
59
|
+
case 'left': {
|
|
60
|
+
return isRTL(element) ? 'right' : 'left'
|
|
61
|
+
}
|
|
62
|
+
default: {
|
|
63
|
+
return placement as Placement
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
52
68
|
export const CPopover: FC<CPopoverProps> = ({
|
|
53
69
|
children,
|
|
54
70
|
className,
|
|
@@ -62,33 +78,53 @@ export const CPopover: FC<CPopoverProps> = ({
|
|
|
62
78
|
visible,
|
|
63
79
|
...rest
|
|
64
80
|
}) => {
|
|
81
|
+
const popoverRef = useRef(null)
|
|
82
|
+
const togglerRef = useRef(null)
|
|
83
|
+
const popper = useRef<Instance>()
|
|
65
84
|
const [_visible, setVisible] = useState(visible)
|
|
66
|
-
const popoverRef = useRef()
|
|
67
|
-
|
|
68
|
-
const [referenceElement, setReferenceElement] = useState(null)
|
|
69
|
-
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null)
|
|
70
|
-
const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null)
|
|
71
|
-
const { styles, attributes } = usePopper(referenceElement, popperElement, {
|
|
72
|
-
modifiers: [
|
|
73
|
-
{ name: 'arrow', options: { element: arrowElement } },
|
|
74
|
-
{
|
|
75
|
-
name: 'offset',
|
|
76
|
-
options: {
|
|
77
|
-
offset: offset,
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
placement: placement,
|
|
82
|
-
})
|
|
83
85
|
|
|
84
86
|
useEffect(() => {
|
|
85
87
|
setVisible(visible)
|
|
86
88
|
}, [visible])
|
|
87
89
|
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (_visible) {
|
|
92
|
+
initPopper()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return () => {
|
|
96
|
+
destroyPopper()
|
|
97
|
+
}
|
|
98
|
+
}, [_visible])
|
|
99
|
+
|
|
100
|
+
const initPopper = () => {
|
|
101
|
+
if (togglerRef.current && popoverRef.current) {
|
|
102
|
+
popper.current = createPopper(togglerRef.current, popoverRef.current, {
|
|
103
|
+
modifiers: [
|
|
104
|
+
{
|
|
105
|
+
name: 'offset',
|
|
106
|
+
options: {
|
|
107
|
+
offset: offset,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
placement: getPlacement(placement, togglerRef.current),
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const destroyPopper = () => {
|
|
117
|
+
if (popper.current) {
|
|
118
|
+
popper.current.destroy()
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
popper.current = undefined
|
|
122
|
+
}
|
|
123
|
+
|
|
88
124
|
return (
|
|
89
125
|
<>
|
|
90
126
|
{React.cloneElement(children as React.ReactElement<any>, {
|
|
91
|
-
ref:
|
|
127
|
+
ref: togglerRef,
|
|
92
128
|
...((trigger === 'click' || trigger.includes('click')) && {
|
|
93
129
|
onClick: () => setVisible(!_visible),
|
|
94
130
|
}),
|
|
@@ -119,20 +155,20 @@ export const CPopover: FC<CPopoverProps> = ({
|
|
|
119
155
|
<div
|
|
120
156
|
className={classNames(
|
|
121
157
|
'popover',
|
|
122
|
-
`bs-popover-${placement
|
|
158
|
+
`bs-popover-${getPlacement(placement, togglerRef.current)
|
|
159
|
+
.replace('left', 'start')
|
|
160
|
+
.replace('right', 'end')}`,
|
|
123
161
|
'fade',
|
|
124
162
|
{
|
|
125
163
|
show: state === 'entered',
|
|
126
164
|
},
|
|
127
165
|
className,
|
|
128
166
|
)}
|
|
129
|
-
ref={
|
|
167
|
+
ref={popoverRef}
|
|
130
168
|
role="tooltip"
|
|
131
|
-
style={styles.popper}
|
|
132
|
-
{...attributes.popper}
|
|
133
169
|
{...rest}
|
|
134
170
|
>
|
|
135
|
-
<div className="popover-arrow"
|
|
171
|
+
<div data-popper-arrow className="popover-arrow"></div>
|
|
136
172
|
<div className="popover-header">{title}</div>
|
|
137
173
|
<div className="popover-body">{content}</div>
|
|
138
174
|
</div>
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import React, { FC, HTMLAttributes, ReactNode,
|
|
1
|
+
import React, { FC, HTMLAttributes, ReactNode, useRef, useEffect, useState } from 'react'
|
|
2
2
|
import { createPortal } from 'react-dom'
|
|
3
|
-
import PropTypes from 'prop-types'
|
|
4
3
|
import classNames from 'classnames'
|
|
5
|
-
import
|
|
4
|
+
import PropTypes from 'prop-types'
|
|
6
5
|
import { Transition } from 'react-transition-group'
|
|
6
|
+
import { createPopper, Instance, Placement } from '@popperjs/core'
|
|
7
7
|
|
|
8
8
|
import { triggerPropType } from '../../props'
|
|
9
9
|
import type { Triggers } from '../../types'
|
|
10
|
+
import { isRTL } from '../../utils'
|
|
10
11
|
|
|
11
|
-
export interface CTooltipProps extends HTMLAttributes<HTMLDivElement> {
|
|
12
|
+
export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {
|
|
12
13
|
/**
|
|
13
14
|
* A string of all className you want applied to the component.
|
|
14
15
|
*/
|
|
@@ -18,7 +19,7 @@ export interface CTooltipProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
18
19
|
*/
|
|
19
20
|
content: ReactNode | string
|
|
20
21
|
/**
|
|
21
|
-
* Offset of the
|
|
22
|
+
* Offset of the tooltip relative to its target.
|
|
22
23
|
*/
|
|
23
24
|
offset?: [number, number]
|
|
24
25
|
/**
|
|
@@ -40,16 +41,31 @@ export interface CTooltipProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
40
41
|
*/
|
|
41
42
|
placement?: 'auto' | 'top' | 'right' | 'bottom' | 'left'
|
|
42
43
|
/**
|
|
43
|
-
* Toggle the visibility of
|
|
44
|
+
* Toggle the visibility of tooltip component.
|
|
44
45
|
*/
|
|
45
46
|
visible?: boolean
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
const getPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
|
|
50
|
+
console.log(element)
|
|
51
|
+
switch (placement) {
|
|
52
|
+
case 'right': {
|
|
53
|
+
return isRTL(element) ? 'left' : 'right'
|
|
54
|
+
}
|
|
55
|
+
case 'left': {
|
|
56
|
+
return isRTL(element) ? 'right' : 'left'
|
|
57
|
+
}
|
|
58
|
+
default: {
|
|
59
|
+
return placement as Placement
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
48
64
|
export const CTooltip: FC<CTooltipProps> = ({
|
|
49
65
|
children,
|
|
50
66
|
className,
|
|
51
67
|
content,
|
|
52
|
-
offset = [0,
|
|
68
|
+
offset = [0, 6],
|
|
53
69
|
onHide,
|
|
54
70
|
onShow,
|
|
55
71
|
placement = 'top',
|
|
@@ -57,33 +73,53 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
57
73
|
visible,
|
|
58
74
|
...rest
|
|
59
75
|
}) => {
|
|
60
|
-
const tooltipRef = useRef()
|
|
76
|
+
const tooltipRef = useRef(null)
|
|
77
|
+
const togglerRef = useRef(null)
|
|
78
|
+
const popper = useRef<Instance>()
|
|
61
79
|
const [_visible, setVisible] = useState(visible)
|
|
62
80
|
|
|
63
|
-
const [referenceElement, setReferenceElement] = useState(null)
|
|
64
|
-
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null)
|
|
65
|
-
const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null)
|
|
66
|
-
const { styles, attributes } = usePopper(referenceElement, popperElement, {
|
|
67
|
-
modifiers: [
|
|
68
|
-
{ name: 'arrow', options: { element: arrowElement } },
|
|
69
|
-
{
|
|
70
|
-
name: 'offset',
|
|
71
|
-
options: {
|
|
72
|
-
offset: offset,
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
placement: placement,
|
|
77
|
-
})
|
|
78
|
-
|
|
79
81
|
useEffect(() => {
|
|
80
82
|
setVisible(visible)
|
|
81
83
|
}, [visible])
|
|
82
84
|
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (_visible) {
|
|
87
|
+
initPopper()
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return () => {
|
|
91
|
+
destroyPopper()
|
|
92
|
+
}
|
|
93
|
+
}, [_visible])
|
|
94
|
+
|
|
95
|
+
const initPopper = () => {
|
|
96
|
+
if (togglerRef.current && tooltipRef.current) {
|
|
97
|
+
popper.current = createPopper(togglerRef.current, tooltipRef.current, {
|
|
98
|
+
modifiers: [
|
|
99
|
+
{
|
|
100
|
+
name: 'offset',
|
|
101
|
+
options: {
|
|
102
|
+
offset: offset,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
placement: getPlacement(placement, togglerRef.current),
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const destroyPopper = () => {
|
|
112
|
+
if (popper.current) {
|
|
113
|
+
popper.current.destroy()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
popper.current = undefined
|
|
117
|
+
}
|
|
118
|
+
|
|
83
119
|
return (
|
|
84
120
|
<>
|
|
85
121
|
{React.cloneElement(children as React.ReactElement<any>, {
|
|
86
|
-
ref:
|
|
122
|
+
ref: togglerRef,
|
|
87
123
|
...((trigger === 'click' || trigger.includes('click')) && {
|
|
88
124
|
onClick: () => setVisible(!_visible),
|
|
89
125
|
}),
|
|
@@ -101,7 +137,6 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
101
137
|
<Transition
|
|
102
138
|
in={_visible}
|
|
103
139
|
mountOnEnter
|
|
104
|
-
nodeRef={tooltipRef}
|
|
105
140
|
onEnter={onShow}
|
|
106
141
|
onExit={onHide}
|
|
107
142
|
timeout={{
|
|
@@ -114,20 +149,20 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
114
149
|
<div
|
|
115
150
|
className={classNames(
|
|
116
151
|
'tooltip',
|
|
117
|
-
`bs-
|
|
152
|
+
`bs-tooltip-${getPlacement(placement, togglerRef.current)
|
|
153
|
+
.replace('left', 'start')
|
|
154
|
+
.replace('right', 'end')}`,
|
|
118
155
|
'fade',
|
|
119
156
|
{
|
|
120
157
|
show: state === 'entered',
|
|
121
158
|
},
|
|
122
159
|
className,
|
|
123
160
|
)}
|
|
124
|
-
ref={
|
|
161
|
+
ref={tooltipRef}
|
|
125
162
|
role="tooltip"
|
|
126
|
-
style={styles.popper}
|
|
127
|
-
{...attributes.popper}
|
|
128
163
|
{...rest}
|
|
129
164
|
>
|
|
130
|
-
<div className="tooltip-arrow"
|
|
165
|
+
<div data-popper-arrow className="tooltip-arrow"></div>
|
|
131
166
|
<div className="tooltip-inner">{content}</div>
|
|
132
167
|
</div>
|
|
133
168
|
)}
|
package/src/utils/index.ts
CHANGED