@coreui/react 4.9.0-alpha.0 → 4.9.0-beta.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/components/accordion/index.d.ts +1 -1
- package/dist/components/tooltip/CTooltip.d.ts +2 -2
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/useColorModes.d.ts +6 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +184 -243
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +185 -242
- package/dist/index.js.map +1 -1
- package/dist/props.d.ts +1 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/isRTL.d.ts +2 -0
- package/package.json +9 -9
- package/src/components/accordion/index.ts +1 -7
- package/src/components/dropdown/CDropdownMenu.tsx +5 -4
- package/src/components/form/CFormSelect.tsx +3 -1
- package/src/components/modal/CModal.tsx +2 -0
- package/src/components/popover/CPopover.tsx +60 -25
- package/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap +2 -1
- package/src/components/progress/CProgress.tsx +1 -0
- package/src/components/sidebar/CSidebar.tsx +2 -2
- package/src/components/spinner/CSpinner.tsx +4 -2
- package/src/components/spinner/__tests__/__snapshots__/CSpinner.spec.tsx.snap +2 -2
- package/src/components/table/CTable.tsx +2 -1
- package/src/components/tooltip/CTooltip.tsx +64 -30
- package/src/components/tooltip/__tests__/CTooltip.spec.tsx +1 -1
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useColorModes.ts +55 -0
- package/src/hooks/useForkedRef.ts +1 -1
- package/src/index.ts +1 -0
- package/src/props.ts +4 -1
- package/src/utils/index.ts +2 -1
- package/src/utils/isRTL.ts +13 -0
- package/src/components/accordion/__tests__/__snapshots__/CAccordionCollapse.spec.tsx.snap +0 -11
package/dist/props.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export declare const colorPropType: PropTypes.Requireable<string>;
|
|
|
4
4
|
export declare const placementPropType: PropTypes.Requireable<Placements>;
|
|
5
5
|
export declare const shapePropType: PropTypes.Requireable<string>;
|
|
6
6
|
export declare const textColorsPropType: PropTypes.Requireable<string>;
|
|
7
|
-
export declare const triggerPropType: PropTypes.Requireable<Triggers
|
|
7
|
+
export declare const triggerPropType: PropTypes.Requireable<NonNullable<Triggers | NonNullable<Triggers>[] | null | undefined>>;
|
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.9.0-
|
|
3
|
+
"version": "4.9.0-beta.0",
|
|
4
4
|
"description": "UI Components Library for React.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"test:update": "jest --coverage --updateSnapshot"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@popperjs/core": "^2.11.
|
|
41
|
-
"@rollup/plugin-commonjs": "^
|
|
42
|
-
"@rollup/plugin-node-resolve": "^15.0
|
|
43
|
-
"@rollup/plugin-typescript": "^11.1.
|
|
40
|
+
"@popperjs/core": "^2.11.8",
|
|
41
|
+
"@rollup/plugin-commonjs": "^25.0.1",
|
|
42
|
+
"@rollup/plugin-node-resolve": "^15.1.0",
|
|
43
|
+
"@rollup/plugin-typescript": "^11.1.1",
|
|
44
44
|
"@testing-library/jest-dom": "^5.16.5",
|
|
45
45
|
"@testing-library/react": "^14.0.0",
|
|
46
|
-
"@types/react": "18.2.
|
|
46
|
+
"@types/react": "18.2.11",
|
|
47
47
|
"@types/react-dom": "^18.2.4",
|
|
48
48
|
"@types/react-transition-group": "^4.4.6",
|
|
49
49
|
"classnames": "^2.3.2",
|
|
@@ -54,13 +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.
|
|
58
|
-
"tslib": "^2.5.
|
|
57
|
+
"rollup": "^3.25.0",
|
|
58
|
+
"tslib": "^2.5.3",
|
|
59
59
|
"ts-jest": "^29.1.0",
|
|
60
60
|
"typescript": "^4.9.5"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
|
-
"@coreui/coreui": "4.3.0-
|
|
63
|
+
"@coreui/coreui": "4.3.0-beta.0",
|
|
64
64
|
"react": ">=17",
|
|
65
65
|
"react-dom": ">=17"
|
|
66
66
|
}
|
|
@@ -4,10 +4,4 @@ import { CAccordionButton } from './CAccordionButton'
|
|
|
4
4
|
import { CAccordionHeader } from './CAccordionHeader'
|
|
5
5
|
import { CAccordionItem } from './CAccordionItem'
|
|
6
6
|
|
|
7
|
-
export {
|
|
8
|
-
CAccordion,
|
|
9
|
-
CAccordionBody,
|
|
10
|
-
CAccordionButton,
|
|
11
|
-
CAccordionHeader,
|
|
12
|
-
CAccordionItem,
|
|
13
|
-
}
|
|
7
|
+
export { CAccordion, CAccordionBody, CAccordionButton, CAccordionHeader, CAccordionItem }
|
|
@@ -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>) => (
|
|
@@ -9,6 +9,7 @@ type Option = {
|
|
|
9
9
|
label?: string
|
|
10
10
|
value?: string
|
|
11
11
|
}
|
|
12
|
+
|
|
12
13
|
export interface CFormSelectProps
|
|
13
14
|
extends CFormControlWrapperProps,
|
|
14
15
|
Omit<InputHTMLAttributes<HTMLSelectElement>, 'size'> {
|
|
@@ -102,7 +103,8 @@ export const CFormSelect = forwardRef<HTMLSelectElement, CFormSelectProps>(
|
|
|
102
103
|
<option
|
|
103
104
|
{...(typeof option === 'object' &&
|
|
104
105
|
option.disabled && { disabled: option.disabled })}
|
|
105
|
-
{...(typeof option === 'object' &&
|
|
106
|
+
{...(typeof option === 'object' &&
|
|
107
|
+
option.value !== undefined && { value: option.value })}
|
|
106
108
|
key={index}
|
|
107
109
|
>
|
|
108
110
|
{typeof option === 'string' ? option : option.label}
|
|
@@ -142,6 +142,7 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
|
|
|
142
142
|
return setStaticBackdrop(true)
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
setVisible(false)
|
|
145
146
|
return onClose && onClose()
|
|
146
147
|
}
|
|
147
148
|
|
|
@@ -174,6 +175,7 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
|
|
|
174
175
|
document.body.style.removeProperty('padding-right')
|
|
175
176
|
}
|
|
176
177
|
}
|
|
178
|
+
|
|
177
179
|
return () => {
|
|
178
180
|
document.body.classList.remove('modal-open')
|
|
179
181
|
if (backdrop) {
|
|
@@ -1,12 +1,13 @@
|
|
|
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
12
|
export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'content'> {
|
|
12
13
|
/**
|
|
@@ -49,6 +50,20 @@ 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
|
+
switch (placement) {
|
|
55
|
+
case 'right': {
|
|
56
|
+
return isRTL(element) ? 'left' : 'right'
|
|
57
|
+
}
|
|
58
|
+
case 'left': {
|
|
59
|
+
return isRTL(element) ? 'right' : 'left'
|
|
60
|
+
}
|
|
61
|
+
default: {
|
|
62
|
+
return placement as Placement
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
52
67
|
export const CPopover: FC<CPopoverProps> = ({
|
|
53
68
|
children,
|
|
54
69
|
className,
|
|
@@ -62,33 +77,53 @@ export const CPopover: FC<CPopoverProps> = ({
|
|
|
62
77
|
visible,
|
|
63
78
|
...rest
|
|
64
79
|
}) => {
|
|
80
|
+
const popoverRef = useRef(null)
|
|
81
|
+
const togglerRef = useRef(null)
|
|
82
|
+
const popper = useRef<Instance>()
|
|
65
83
|
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
84
|
|
|
84
85
|
useEffect(() => {
|
|
85
86
|
setVisible(visible)
|
|
86
87
|
}, [visible])
|
|
87
88
|
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (_visible) {
|
|
91
|
+
initPopper()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return () => {
|
|
95
|
+
destroyPopper()
|
|
96
|
+
}
|
|
97
|
+
}, [_visible])
|
|
98
|
+
|
|
99
|
+
const initPopper = () => {
|
|
100
|
+
if (togglerRef.current && popoverRef.current) {
|
|
101
|
+
popper.current = createPopper(togglerRef.current, popoverRef.current, {
|
|
102
|
+
modifiers: [
|
|
103
|
+
{
|
|
104
|
+
name: 'offset',
|
|
105
|
+
options: {
|
|
106
|
+
offset: offset,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
placement: getPlacement(placement, togglerRef.current),
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const destroyPopper = () => {
|
|
116
|
+
if (popper.current) {
|
|
117
|
+
popper.current.destroy()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
popper.current = undefined
|
|
121
|
+
}
|
|
122
|
+
|
|
88
123
|
return (
|
|
89
124
|
<>
|
|
90
125
|
{React.cloneElement(children as React.ReactElement<any>, {
|
|
91
|
-
ref:
|
|
126
|
+
ref: togglerRef,
|
|
92
127
|
...((trigger === 'click' || trigger.includes('click')) && {
|
|
93
128
|
onClick: () => setVisible(!_visible),
|
|
94
129
|
}),
|
|
@@ -119,20 +154,20 @@ export const CPopover: FC<CPopoverProps> = ({
|
|
|
119
154
|
<div
|
|
120
155
|
className={classNames(
|
|
121
156
|
'popover',
|
|
122
|
-
`bs-popover-${placement
|
|
157
|
+
`bs-popover-${getPlacement(placement, togglerRef.current)
|
|
158
|
+
.replace('left', 'start')
|
|
159
|
+
.replace('right', 'end')}`,
|
|
123
160
|
'fade',
|
|
124
161
|
{
|
|
125
162
|
show: state === 'entered',
|
|
126
163
|
},
|
|
127
164
|
className,
|
|
128
165
|
)}
|
|
129
|
-
ref={
|
|
166
|
+
ref={popoverRef}
|
|
130
167
|
role="tooltip"
|
|
131
|
-
style={styles.popper}
|
|
132
|
-
{...attributes.popper}
|
|
133
168
|
{...rest}
|
|
134
169
|
>
|
|
135
|
-
<div className="popover-arrow"
|
|
170
|
+
<div data-popper-arrow className="popover-arrow"></div>
|
|
136
171
|
<div className="popover-header">{title}</div>
|
|
137
172
|
<div className="popover-body">{content}</div>
|
|
138
173
|
</div>
|
|
@@ -11,10 +11,11 @@ exports[`CPopover customize 1`] = `
|
|
|
11
11
|
<div
|
|
12
12
|
class="popover bs-popover-end fade"
|
|
13
13
|
role="tooltip"
|
|
14
|
-
style="position: absolute; left: 0px; top: 0px;"
|
|
14
|
+
style="position: absolute; left: 0px; top: 0px; margin: 0px;"
|
|
15
15
|
>
|
|
16
16
|
<div
|
|
17
17
|
class="popover-arrow"
|
|
18
|
+
data-popper-arrow="true"
|
|
18
19
|
style="position: absolute;"
|
|
19
20
|
/>
|
|
20
21
|
<div
|
|
@@ -29,6 +29,7 @@ export interface CProgressProps
|
|
|
29
29
|
white?: boolean
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// TODO: update markup and add '.progress-stacked' in v5
|
|
32
33
|
export const CProgress = forwardRef<HTMLDivElement, CProgressProps>(
|
|
33
34
|
({ children, className, height, thin, value = 0, white, ...rest }, ref) => {
|
|
34
35
|
return (
|
|
@@ -98,7 +98,7 @@ export const CSidebar = forwardRef<HTMLDivElement, CSidebarProps>(
|
|
|
98
98
|
sidebarRef.current && setMobile(isOnMobile(sidebarRef.current))
|
|
99
99
|
sidebarRef.current && setInViewport(isInViewport(sidebarRef.current))
|
|
100
100
|
|
|
101
|
-
window.addEventListener('resize',
|
|
101
|
+
window.addEventListener('resize', handleResize)
|
|
102
102
|
window.addEventListener('mouseup', handleClickOutside)
|
|
103
103
|
window.addEventListener('keyup', handleKeyup)
|
|
104
104
|
|
|
@@ -108,7 +108,7 @@ export const CSidebar = forwardRef<HTMLDivElement, CSidebarProps>(
|
|
|
108
108
|
})
|
|
109
109
|
|
|
110
110
|
return () => {
|
|
111
|
-
window.removeEventListener('resize',
|
|
111
|
+
window.removeEventListener('resize', handleResize)
|
|
112
112
|
window.removeEventListener('mouseup', handleClickOutside)
|
|
113
113
|
window.removeEventListener('keyup', handleKeyup)
|
|
114
114
|
|
|
@@ -51,8 +51,10 @@ export const CSpinner = forwardRef<HTMLDivElement | HTMLSpanElement, CSpinnerPro
|
|
|
51
51
|
<Component
|
|
52
52
|
className={classNames(
|
|
53
53
|
`spinner-${variant}`,
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
{
|
|
55
|
+
[`spinner-${variant}-${size}`]: size,
|
|
56
|
+
[`text-${color}`]: color,
|
|
57
|
+
},
|
|
56
58
|
className,
|
|
57
59
|
)}
|
|
58
60
|
role="status"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`CSpinner customize 1`] = `
|
|
4
4
|
<div>
|
|
5
5
|
<h3
|
|
6
|
-
class="spinner-grow
|
|
6
|
+
class="spinner-grow spinner-grow-sm text-warning bazinga"
|
|
7
7
|
role="status"
|
|
8
8
|
>
|
|
9
9
|
<span
|
|
@@ -18,7 +18,7 @@ exports[`CSpinner customize 1`] = `
|
|
|
18
18
|
exports[`loads and displays CSpinner component 1`] = `
|
|
19
19
|
<div>
|
|
20
20
|
<div
|
|
21
|
-
class="spinner-border
|
|
21
|
+
class="spinner-border"
|
|
22
22
|
role="status"
|
|
23
23
|
>
|
|
24
24
|
<span
|
|
@@ -201,7 +201,8 @@ export const CTable = forwardRef<HTMLTableElement, CTableProps>(
|
|
|
201
201
|
<CTableRow {...(item._props && { ...item._props })} key={index}>
|
|
202
202
|
{columnNames &&
|
|
203
203
|
columnNames.map((colName: string, index: number) => {
|
|
204
|
-
|
|
204
|
+
// eslint-disable-next-line unicorn/no-negated-condition
|
|
205
|
+
return item[colName] !== undefined ? (
|
|
205
206
|
<CTableDataCell
|
|
206
207
|
{...(item._cellProps && {
|
|
207
208
|
...(item._cellProps['all'] && { ...item._cellProps['all'] }),
|
|
@@ -1,12 +1,13 @@
|
|
|
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
12
|
export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {
|
|
12
13
|
/**
|
|
@@ -18,7 +19,7 @@ export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'con
|
|
|
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,30 @@ export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'con
|
|
|
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
|
+
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
|
+
|
|
48
63
|
export const CTooltip: FC<CTooltipProps> = ({
|
|
49
64
|
children,
|
|
50
65
|
className,
|
|
51
66
|
content,
|
|
52
|
-
offset = [0,
|
|
67
|
+
offset = [0, 6],
|
|
53
68
|
onHide,
|
|
54
69
|
onShow,
|
|
55
70
|
placement = 'top',
|
|
@@ -57,33 +72,53 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
57
72
|
visible,
|
|
58
73
|
...rest
|
|
59
74
|
}) => {
|
|
60
|
-
const tooltipRef = useRef()
|
|
75
|
+
const tooltipRef = useRef(null)
|
|
76
|
+
const togglerRef = useRef(null)
|
|
77
|
+
const popper = useRef<Instance>()
|
|
61
78
|
const [_visible, setVisible] = useState(visible)
|
|
62
79
|
|
|
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
80
|
useEffect(() => {
|
|
80
81
|
setVisible(visible)
|
|
81
82
|
}, [visible])
|
|
82
83
|
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (_visible) {
|
|
86
|
+
initPopper()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return () => {
|
|
90
|
+
destroyPopper()
|
|
91
|
+
}
|
|
92
|
+
}, [_visible])
|
|
93
|
+
|
|
94
|
+
const initPopper = () => {
|
|
95
|
+
if (togglerRef.current && tooltipRef.current) {
|
|
96
|
+
popper.current = createPopper(togglerRef.current, tooltipRef.current, {
|
|
97
|
+
modifiers: [
|
|
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()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
popper.current = undefined
|
|
116
|
+
}
|
|
117
|
+
|
|
83
118
|
return (
|
|
84
119
|
<>
|
|
85
120
|
{React.cloneElement(children as React.ReactElement<any>, {
|
|
86
|
-
ref:
|
|
121
|
+
ref: togglerRef,
|
|
87
122
|
...((trigger === 'click' || trigger.includes('click')) && {
|
|
88
123
|
onClick: () => setVisible(!_visible),
|
|
89
124
|
}),
|
|
@@ -101,7 +136,6 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
101
136
|
<Transition
|
|
102
137
|
in={_visible}
|
|
103
138
|
mountOnEnter
|
|
104
|
-
nodeRef={tooltipRef}
|
|
105
139
|
onEnter={onShow}
|
|
106
140
|
onExit={onHide}
|
|
107
141
|
timeout={{
|
|
@@ -114,20 +148,20 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
114
148
|
<div
|
|
115
149
|
className={classNames(
|
|
116
150
|
'tooltip',
|
|
117
|
-
`bs-
|
|
151
|
+
`bs-tooltip-${getPlacement(placement, togglerRef.current)
|
|
152
|
+
.replace('left', 'start')
|
|
153
|
+
.replace('right', 'end')}`,
|
|
118
154
|
'fade',
|
|
119
155
|
{
|
|
120
156
|
show: state === 'entered',
|
|
121
157
|
},
|
|
122
158
|
className,
|
|
123
159
|
)}
|
|
124
|
-
ref={
|
|
160
|
+
ref={tooltipRef}
|
|
125
161
|
role="tooltip"
|
|
126
|
-
style={styles.popper}
|
|
127
|
-
{...attributes.popper}
|
|
128
162
|
{...rest}
|
|
129
163
|
>
|
|
130
|
-
<div className="tooltip-arrow"
|
|
164
|
+
<div data-popper-arrow className="tooltip-arrow"></div>
|
|
131
165
|
<div className="tooltip-inner">{content}</div>
|
|
132
166
|
</div>
|
|
133
167
|
)}
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
interface UseColorModesOutput {
|
|
4
|
+
getColorMode: () => string
|
|
5
|
+
setColorMode: (mode: string) => void
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const getStoredTheme = (localStorageItemName: string) => localStorage.getItem(localStorageItemName)
|
|
9
|
+
const setStoredTheme = (localStorageItemName: string, colorMode: string) =>
|
|
10
|
+
localStorage.setItem(localStorageItemName, colorMode)
|
|
11
|
+
|
|
12
|
+
const getPreferredColorScheme = (localStorageItemName: string) => {
|
|
13
|
+
const storedTheme = getStoredTheme(localStorageItemName)
|
|
14
|
+
|
|
15
|
+
if (storedTheme) {
|
|
16
|
+
return storedTheme
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const setTheme = (colorMode: string) => {
|
|
23
|
+
document.documentElement.dataset.coreuiTheme =
|
|
24
|
+
colorMode === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
25
|
+
? 'dark'
|
|
26
|
+
: colorMode
|
|
27
|
+
|
|
28
|
+
const event = new Event('ColorSchemeChange')
|
|
29
|
+
document.documentElement.dispatchEvent(event)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const useColorModes = (
|
|
33
|
+
localStorageItemName = 'coreui-react-color-scheme',
|
|
34
|
+
): UseColorModesOutput => {
|
|
35
|
+
const [colorMode, setColorMode] = useState<string>(getPreferredColorScheme(localStorageItemName))
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
setStoredTheme(localStorageItemName, colorMode)
|
|
39
|
+
setTheme(colorMode)
|
|
40
|
+
}, [colorMode])
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
|
44
|
+
const storedTheme = getStoredTheme(localStorageItemName)
|
|
45
|
+
if (storedTheme !== 'light' && storedTheme !== 'dark') {
|
|
46
|
+
setTheme(colorMode)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
}, [])
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
getColorMode: () => colorMode,
|
|
53
|
+
setColorMode: (mode: string) => setColorMode(mode),
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/index.ts
CHANGED
package/src/props.ts
CHANGED
|
@@ -57,4 +57,7 @@ export const textColorsPropType = PropTypes.oneOfType([
|
|
|
57
57
|
PropTypes.string,
|
|
58
58
|
])
|
|
59
59
|
|
|
60
|
-
export const triggerPropType = PropTypes.
|
|
60
|
+
export const triggerPropType = PropTypes.oneOfType([
|
|
61
|
+
PropTypes.arrayOf(PropTypes.oneOf<Triggers>(['hover', 'focus', 'click']).isRequired),
|
|
62
|
+
PropTypes.oneOf<Triggers>(['hover', 'focus', 'click']),
|
|
63
|
+
])
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const isRTL = (element?: HTMLElement | HTMLDivElement | null) => {
|
|
2
|
+
if (typeof document !== 'undefined' && document.documentElement.dir === 'rtl') {
|
|
3
|
+
return true
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if (element) {
|
|
7
|
+
return element.closest('[dir="rtl"]') !== null
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return false
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default isRTL
|