@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.
- package/README.md +1 -1
- package/dist/cjs/components/button/CButton.js +5 -1
- package/dist/cjs/components/button/CButton.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdown.js +2 -1
- package/dist/cjs/components/dropdown/CDropdown.js.map +1 -1
- package/dist/cjs/components/dropdown/utils.d.ts +0 -1
- package/dist/cjs/components/dropdown/utils.js +0 -13
- package/dist/cjs/components/dropdown/utils.js.map +1 -1
- package/dist/cjs/components/popover/CPopover.js +47 -40
- package/dist/cjs/components/popover/CPopover.js.map +1 -1
- package/dist/cjs/components/tabs/CTab.d.ts +12 -0
- package/dist/cjs/components/tabs/CTab.js +25 -0
- package/dist/cjs/components/tabs/CTab.js.map +1 -0
- package/dist/cjs/components/tabs/CTabList.d.ts +16 -0
- package/dist/cjs/components/tabs/CTabList.js +54 -0
- package/dist/cjs/components/tabs/CTabList.js.map +1 -0
- package/dist/cjs/components/tabs/CTabPane.d.ts +6 -0
- package/dist/cjs/components/tabs/CTabPane.js +4 -2
- package/dist/cjs/components/tabs/CTabPane.js.map +1 -1
- package/dist/cjs/components/tabs/CTabPanel.d.ts +28 -0
- package/dist/cjs/components/tabs/CTabPanel.js +43 -0
- package/dist/cjs/components/tabs/CTabPanel.js.map +1 -0
- package/dist/cjs/components/tabs/CTabs.d.ts +22 -0
- package/dist/cjs/components/tabs/CTabs.js +28 -0
- package/dist/cjs/components/tabs/CTabs.js.map +1 -0
- package/dist/cjs/components/tabs/index.d.ts +5 -1
- package/dist/cjs/components/tooltip/CTooltip.js +50 -40
- package/dist/cjs/components/tooltip/CTooltip.js.map +1 -1
- package/dist/cjs/hooks/useForkedRef.d.ts +0 -1
- package/dist/cjs/hooks/usePopper.d.ts +1 -0
- package/dist/cjs/hooks/usePopper.js +11 -4
- package/dist/cjs/hooks/usePopper.js.map +1 -1
- package/dist/cjs/index.js +8 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/node_modules/react-transition-group/esm/CSSTransition.js +1 -2
- package/dist/cjs/node_modules/react-transition-group/esm/CSSTransition.js.map +1 -1
- package/dist/cjs/node_modules/react-transition-group/esm/Transition.js +1 -2
- package/dist/cjs/node_modules/react-transition-group/esm/Transition.js.map +1 -1
- package/dist/cjs/utils/getNextActiveElement.d.ts +2 -0
- package/dist/cjs/utils/getNextActiveElement.js +19 -0
- package/dist/cjs/utils/getNextActiveElement.js.map +1 -0
- package/dist/cjs/utils/index.d.ts +2 -1
- package/dist/esm/components/button/CButton.js +5 -1
- package/dist/esm/components/button/CButton.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdown.js +2 -1
- package/dist/esm/components/dropdown/CDropdown.js.map +1 -1
- package/dist/esm/components/dropdown/utils.d.ts +0 -1
- package/dist/esm/components/dropdown/utils.js +1 -13
- package/dist/esm/components/dropdown/utils.js.map +1 -1
- package/dist/esm/components/popover/CPopover.js +47 -40
- package/dist/esm/components/popover/CPopover.js.map +1 -1
- package/dist/esm/components/tabs/CTab.d.ts +12 -0
- package/dist/esm/components/tabs/CTab.js +23 -0
- package/dist/esm/components/tabs/CTab.js.map +1 -0
- package/dist/esm/components/tabs/CTabList.d.ts +16 -0
- package/dist/esm/components/tabs/CTabList.js +52 -0
- package/dist/esm/components/tabs/CTabList.js.map +1 -0
- package/dist/esm/components/tabs/CTabPane.d.ts +6 -0
- package/dist/esm/components/tabs/CTabPane.js +4 -2
- package/dist/esm/components/tabs/CTabPane.js.map +1 -1
- package/dist/esm/components/tabs/CTabPanel.d.ts +28 -0
- package/dist/esm/components/tabs/CTabPanel.js +41 -0
- package/dist/esm/components/tabs/CTabPanel.js.map +1 -0
- package/dist/esm/components/tabs/CTabs.d.ts +22 -0
- package/dist/esm/components/tabs/CTabs.js +25 -0
- package/dist/esm/components/tabs/CTabs.js.map +1 -0
- package/dist/esm/components/tabs/index.d.ts +5 -1
- package/dist/esm/components/tooltip/CTooltip.js +50 -40
- package/dist/esm/components/tooltip/CTooltip.js.map +1 -1
- package/dist/esm/hooks/useForkedRef.d.ts +0 -1
- package/dist/esm/hooks/usePopper.d.ts +1 -0
- package/dist/esm/hooks/usePopper.js +11 -4
- package/dist/esm/hooks/usePopper.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/node_modules/react-transition-group/esm/CSSTransition.js +1 -2
- package/dist/esm/node_modules/react-transition-group/esm/CSSTransition.js.map +1 -1
- package/dist/esm/node_modules/react-transition-group/esm/Transition.js +1 -2
- package/dist/esm/node_modules/react-transition-group/esm/Transition.js.map +1 -1
- package/dist/esm/utils/getNextActiveElement.d.ts +2 -0
- package/dist/esm/utils/getNextActiveElement.js +15 -0
- package/dist/esm/utils/getNextActiveElement.js.map +1 -0
- package/dist/esm/utils/index.d.ts +2 -1
- package/package.json +13 -13
- package/src/components/button/CButton.tsx +5 -2
- package/src/components/button/__tests__/CButton.spec.tsx +1 -1
- package/src/components/button-group/__tests__/CButtonGroup.spec.tsx +6 -6
- package/src/components/button-group/__tests__/CButtonToolbar.spec.tsx +6 -6
- package/src/components/dropdown/CDropdown.tsx +2 -2
- package/src/components/dropdown/__tests__/CDropdownToggle.spec.tsx +1 -1
- package/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap +1 -1
- package/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.tsx.snap +1 -1
- package/src/components/dropdown/utils.ts +0 -22
- package/src/components/modal/__tests__/CModal.spec.tsx +1 -1
- package/src/components/nav/__tests__/__snapshots__/CNavItem.spec.tsx.snap +12 -8
- package/src/components/popover/CPopover.tsx +59 -66
- package/src/components/popover/__tests__/CPopover.spec.tsx +2 -2
- package/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap +22 -0
- package/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.tsx.snap +4 -4
- package/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.tsx.snap +6 -2
- package/src/components/tabs/CTab.tsx +56 -0
- package/src/components/tabs/CTabList.tsx +92 -0
- package/src/components/tabs/CTabPane.tsx +9 -2
- package/src/components/tabs/CTabPanel.tsx +98 -0
- package/src/components/tabs/CTabs.tsx +54 -0
- package/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.tsx.snap +1 -1
- package/src/components/tabs/index.ts +5 -1
- package/src/components/toast/__tests__/__snapshots__/CToaster.spec.tsx.snap +1 -1
- package/src/components/tooltip/CTooltip.tsx +63 -66
- package/src/components/tooltip/__tests__/__snapshots__/CTooltip.spec.tsx.snap +1 -0
- package/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.tsx.snap +1 -1
- package/src/hooks/usePopper.ts +15 -5
- package/src/utils/getNextActiveElement.ts +23 -0
- package/src/utils/index.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreui/react",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "UI Components Library for React.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -41,31 +41,31 @@
|
|
|
41
41
|
"test:update": "jest --coverage --updateSnapshot"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@coreui/coreui": "^5.
|
|
44
|
+
"@coreui/coreui": "^5.1.0",
|
|
45
45
|
"@popperjs/core": "^2.11.8",
|
|
46
46
|
"prop-types": "^15.8.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@rollup/plugin-commonjs": "^
|
|
49
|
+
"@rollup/plugin-commonjs": "^26.0.1",
|
|
50
50
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
51
51
|
"@rollup/plugin-typescript": "^11.1.6",
|
|
52
|
-
"@testing-library/jest-dom": "^6.4.
|
|
53
|
-
"@testing-library/react": "^
|
|
52
|
+
"@testing-library/jest-dom": "^6.4.6",
|
|
53
|
+
"@testing-library/react": "^16.0.0",
|
|
54
54
|
"@types/jest": "^29.5.12",
|
|
55
|
-
"@types/react": "18.
|
|
56
|
-
"@types/react-dom": "^18.
|
|
55
|
+
"@types/react": "18.3.3",
|
|
56
|
+
"@types/react-dom": "^18.3.0",
|
|
57
57
|
"@types/react-transition-group": "^4.4.10",
|
|
58
58
|
"classnames": "^2.5.1",
|
|
59
59
|
"cross-env": "^7.0.3",
|
|
60
60
|
"jest": "^29.7.0",
|
|
61
61
|
"jest-environment-jsdom": "^29.7.0",
|
|
62
|
-
"react": "^18.
|
|
63
|
-
"react-dom": "^18.
|
|
62
|
+
"react": "^18.3.1",
|
|
63
|
+
"react-dom": "^18.3.1",
|
|
64
64
|
"react-transition-group": "^4.4.5",
|
|
65
|
-
"rollup": "^4.
|
|
66
|
-
"ts-jest": "^29.1.
|
|
67
|
-
"tslib": "^2.6.
|
|
68
|
-
"typescript": "^5.
|
|
65
|
+
"rollup": "^4.18.0",
|
|
66
|
+
"ts-jest": "^29.1.5",
|
|
67
|
+
"tslib": "^2.6.3",
|
|
68
|
+
"typescript": "^5.5.3"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"react": ">=17",
|
|
@@ -74,8 +74,11 @@ export const CButton: PolymorphicRefForwardingComponent<'button', CButtonProps>
|
|
|
74
74
|
{...(!rest.href && { type: type })}
|
|
75
75
|
className={classNames(
|
|
76
76
|
'btn',
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
{
|
|
78
|
+
[`btn-${color}`]: color && !variant,
|
|
79
|
+
[`btn-${variant}-${color}`]: color && variant,
|
|
80
|
+
[`btn-${size}`]: size,
|
|
81
|
+
},
|
|
79
82
|
shape,
|
|
80
83
|
className,
|
|
81
84
|
)}
|
|
@@ -4,7 +4,7 @@ import '@testing-library/jest-dom'
|
|
|
4
4
|
import { CButton } from '../../../index'
|
|
5
5
|
|
|
6
6
|
test('loads and displays CButton component', async () => {
|
|
7
|
-
const { container } = render(<CButton>Test</CButton>)
|
|
7
|
+
const { container } = render(<CButton color="primary">Test</CButton>)
|
|
8
8
|
expect(container).toMatchSnapshot()
|
|
9
9
|
})
|
|
10
10
|
|
|
@@ -11,9 +11,9 @@ test('loads and displays CButtonGroup component', async () => {
|
|
|
11
11
|
test('CButtonGroup customize', async () => {
|
|
12
12
|
const { container } = render(
|
|
13
13
|
<CButtonGroup className="bazinga" size="lg" vertical={false}>
|
|
14
|
-
<CButton>Test A</CButton>
|
|
15
|
-
<CButton>Test B</CButton>
|
|
16
|
-
<CButton>Test C</CButton>
|
|
14
|
+
<CButton color="primary">Test A</CButton>
|
|
15
|
+
<CButton color="primary">Test B</CButton>
|
|
16
|
+
<CButton color="primary">Test C</CButton>
|
|
17
17
|
</CButtonGroup>,
|
|
18
18
|
)
|
|
19
19
|
expect(container).toMatchSnapshot()
|
|
@@ -25,9 +25,9 @@ test('CButtonGroup customize', async () => {
|
|
|
25
25
|
test('CButtonGroup customize vertical', async () => {
|
|
26
26
|
const { container } = render(
|
|
27
27
|
<CButtonGroup className="bazinga" size="lg" vertical={true}>
|
|
28
|
-
<CButton>Test A</CButton>
|
|
29
|
-
<CButton>Test B</CButton>
|
|
30
|
-
<CButton>Test C</CButton>
|
|
28
|
+
<CButton color="primary">Test A</CButton>
|
|
29
|
+
<CButton color="primary">Test B</CButton>
|
|
30
|
+
<CButton color="primary">Test C</CButton>
|
|
31
31
|
</CButtonGroup>,
|
|
32
32
|
)
|
|
33
33
|
expect(container).toMatchSnapshot()
|
|
@@ -12,14 +12,14 @@ test('CButtonToolbar customize', async () => {
|
|
|
12
12
|
const { container } = render(
|
|
13
13
|
<CButtonToolbar className="bazinga" role="group" aria-label="Bazinga">
|
|
14
14
|
<CButtonGroup role="group">
|
|
15
|
-
<CButton>1</CButton>
|
|
16
|
-
<CButton>2</CButton>
|
|
17
|
-
<CButton>3</CButton>
|
|
15
|
+
<CButton color="primary">1</CButton>
|
|
16
|
+
<CButton color="primary">2</CButton>
|
|
17
|
+
<CButton color="primary">3</CButton>
|
|
18
18
|
</CButtonGroup>
|
|
19
19
|
<CButtonGroup role="group">
|
|
20
|
-
<CButton>A</CButton>
|
|
21
|
-
<CButton>B</CButton>
|
|
22
|
-
<CButton>C</CButton>
|
|
20
|
+
<CButton color="primary">A</CButton>
|
|
21
|
+
<CButton color="primary">B</CButton>
|
|
22
|
+
<CButton color="primary">C</CButton>
|
|
23
23
|
</CButtonGroup>
|
|
24
24
|
</CButtonToolbar>,
|
|
25
25
|
)
|
|
@@ -15,10 +15,10 @@ import { PolymorphicRefForwardingComponent } from '../../helpers'
|
|
|
15
15
|
import { useForkedRef, usePopper } from '../../hooks'
|
|
16
16
|
import { placementPropType } from '../../props'
|
|
17
17
|
import type { Placements } from '../../types'
|
|
18
|
-
import { isRTL } from '../../utils'
|
|
18
|
+
import { getNextActiveElement, isRTL } from '../../utils'
|
|
19
19
|
|
|
20
20
|
import type { Alignments, Directions } from './types'
|
|
21
|
-
import {
|
|
21
|
+
import { getPlacement } from './utils'
|
|
22
22
|
|
|
23
23
|
export interface CDropdownProps extends HTMLAttributes<HTMLDivElement | HTMLLIElement> {
|
|
24
24
|
/**
|
|
@@ -10,7 +10,7 @@ test('loads and displays CDropdownToggle component', async () => {
|
|
|
10
10
|
|
|
11
11
|
test('CDropdownToggle customize', async () => {
|
|
12
12
|
const { container } = render(
|
|
13
|
-
<CDropdownToggle caret={true} split={true} trigger="focus">
|
|
13
|
+
<CDropdownToggle caret={true} color="primary" split={true} trigger="focus">
|
|
14
14
|
Test
|
|
15
15
|
</CDropdownToggle>,
|
|
16
16
|
)
|
|
@@ -19,28 +19,6 @@ export const getAlignmentClassNames = (alignment: Alignments) => {
|
|
|
19
19
|
return classNames
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export const getNextActiveElement = (
|
|
23
|
-
list: HTMLElement[],
|
|
24
|
-
activeElement: HTMLElement,
|
|
25
|
-
shouldGetNext: boolean,
|
|
26
|
-
isCycleAllowed: boolean,
|
|
27
|
-
) => {
|
|
28
|
-
const listLength = list.length
|
|
29
|
-
let index = list.indexOf(activeElement)
|
|
30
|
-
|
|
31
|
-
if (index === -1) {
|
|
32
|
-
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
index += shouldGetNext ? 1 : -1
|
|
36
|
-
|
|
37
|
-
if (isCycleAllowed) {
|
|
38
|
-
index = (index + listLength) % listLength
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return list[Math.max(0, Math.min(index, listLength - 1))]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
22
|
export const getPlacement = (
|
|
45
23
|
placement: Placement,
|
|
46
24
|
direction: string | undefined,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
import { render, fireEvent } from '@testing-library/react'
|
|
3
|
-
import '@testing-library/jest-dom
|
|
3
|
+
import '@testing-library/jest-dom'
|
|
4
4
|
import { CModal } from '../../../index'
|
|
5
5
|
|
|
6
6
|
test('loads and displays CModal component', async () => {
|
|
@@ -2,35 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`CNavItem customize 1`] = `
|
|
4
4
|
<div>
|
|
5
|
-
<
|
|
5
|
+
<h3
|
|
6
6
|
class="nav-item bazinga"
|
|
7
7
|
>
|
|
8
|
-
<
|
|
8
|
+
<a
|
|
9
9
|
aria-current="page"
|
|
10
|
+
aria-disabled="true"
|
|
10
11
|
class="nav-link bazinga active disabled"
|
|
11
12
|
disabled=""
|
|
12
13
|
href="/bazinga"
|
|
14
|
+
tabindex="-1"
|
|
13
15
|
>
|
|
14
16
|
Test
|
|
15
|
-
</
|
|
16
|
-
</
|
|
17
|
+
</a>
|
|
18
|
+
</h3>
|
|
17
19
|
</div>
|
|
18
20
|
`;
|
|
19
21
|
|
|
20
22
|
exports[`CNavItem customize 2`] = `
|
|
21
23
|
<div>
|
|
22
|
-
<
|
|
24
|
+
<h3
|
|
23
25
|
class="nav-item bazinga"
|
|
24
26
|
>
|
|
25
|
-
<
|
|
27
|
+
<a
|
|
26
28
|
aria-current="page"
|
|
29
|
+
aria-disabled="true"
|
|
27
30
|
class="nav-link bazinga active disabled"
|
|
28
31
|
disabled=""
|
|
29
32
|
href="/bazinga"
|
|
33
|
+
tabindex="-1"
|
|
30
34
|
>
|
|
31
35
|
Test
|
|
32
|
-
</
|
|
33
|
-
</
|
|
36
|
+
</a>
|
|
37
|
+
</h3>
|
|
34
38
|
</div>
|
|
35
39
|
`;
|
|
36
40
|
|
|
@@ -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 {
|
|
9
|
+
import { executeAfterTransition, getRTLPlacement } from '../../utils'
|
|
11
10
|
|
|
12
11
|
export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'content'> {
|
|
13
12
|
/**
|
|
@@ -101,6 +100,7 @@ export const CPopover = forwardRef<HTMLDivElement, CPopoverProps>(
|
|
|
101
100
|
const uID = useRef(`popover${Math.floor(Math.random() * 1_000_000)}`)
|
|
102
101
|
|
|
103
102
|
const { initPopper, destroyPopper } = usePopper()
|
|
103
|
+
const [mounted, setMounted] = useState(false)
|
|
104
104
|
const [_visible, setVisible] = useState(visible)
|
|
105
105
|
|
|
106
106
|
const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay
|
|
@@ -133,14 +133,44 @@ export const CPopover = forwardRef<HTMLDivElement, CPopoverProps>(
|
|
|
133
133
|
setVisible(visible)
|
|
134
134
|
}, [visible])
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
if (_visible) {
|
|
138
|
+
setMounted(true)
|
|
139
|
+
|
|
140
|
+
if (popoverRef.current) {
|
|
141
|
+
popoverRef.current.classList.remove('fade', 'show')
|
|
142
|
+
destroyPopper()
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
setTimeout(() => {
|
|
146
|
+
if (togglerRef.current && popoverRef.current) {
|
|
147
|
+
if (animation) {
|
|
148
|
+
popoverRef.current.classList.add('fade')
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
initPopper(togglerRef.current, popoverRef.current, popperConfig)
|
|
152
|
+
popoverRef.current.style.removeProperty('display')
|
|
153
|
+
popoverRef.current.classList.add('show')
|
|
154
|
+
onShow && onShow()
|
|
155
|
+
}
|
|
156
|
+
}, _delay.show)
|
|
140
157
|
}
|
|
141
158
|
|
|
142
|
-
|
|
143
|
-
|
|
159
|
+
return () => {
|
|
160
|
+
if (popoverRef.current) {
|
|
161
|
+
popoverRef.current.classList.remove('show')
|
|
162
|
+
onHide && onHide()
|
|
163
|
+
executeAfterTransition(() => {
|
|
164
|
+
if (popoverRef.current) {
|
|
165
|
+
popoverRef.current.style.display = 'none'
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
destroyPopper()
|
|
169
|
+
setMounted(false)
|
|
170
|
+
}, popoverRef.current)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}, [_visible])
|
|
144
174
|
|
|
145
175
|
return (
|
|
146
176
|
<>
|
|
@@ -150,71 +180,34 @@ export const CPopover = forwardRef<HTMLDivElement, CPopoverProps>(
|
|
|
150
180
|
}),
|
|
151
181
|
ref: togglerRef,
|
|
152
182
|
...((trigger === 'click' || trigger.includes('click')) && {
|
|
153
|
-
onClick: () =>
|
|
183
|
+
onClick: () => setVisible(!_visible),
|
|
154
184
|
}),
|
|
155
185
|
...((trigger === 'focus' || trigger.includes('focus')) && {
|
|
156
|
-
onFocus: () =>
|
|
157
|
-
onBlur: () =>
|
|
186
|
+
onFocus: () => setVisible(true),
|
|
187
|
+
onBlur: () => setVisible(false),
|
|
158
188
|
}),
|
|
159
189
|
...((trigger === 'hover' || trigger.includes('hover')) && {
|
|
160
|
-
onMouseEnter: () =>
|
|
161
|
-
onMouseLeave: () =>
|
|
190
|
+
onMouseEnter: () => setVisible(true),
|
|
191
|
+
onMouseLeave: () => setVisible(false),
|
|
162
192
|
}),
|
|
163
193
|
})}
|
|
164
194
|
<CConditionalPortal container={container} portal={true}>
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
onExit={onHide}
|
|
182
|
-
onExited={() => {
|
|
183
|
-
destroyPopper()
|
|
184
|
-
}}
|
|
185
|
-
timeout={{
|
|
186
|
-
enter: 0,
|
|
187
|
-
exit: popoverRef.current
|
|
188
|
-
? getTransitionDurationFromElement(popoverRef.current) + 50
|
|
189
|
-
: 200,
|
|
190
|
-
}}
|
|
191
|
-
unmountOnExit
|
|
192
|
-
>
|
|
193
|
-
{(state) => (
|
|
194
|
-
<div
|
|
195
|
-
className={classNames(
|
|
196
|
-
'popover',
|
|
197
|
-
'bs-popover-auto',
|
|
198
|
-
{
|
|
199
|
-
fade: animation,
|
|
200
|
-
show: state === 'entered',
|
|
201
|
-
},
|
|
202
|
-
className,
|
|
203
|
-
)}
|
|
204
|
-
id={uID.current}
|
|
205
|
-
ref={forkedRef}
|
|
206
|
-
role="tooltip"
|
|
207
|
-
style={{
|
|
208
|
-
display: 'none',
|
|
209
|
-
}}
|
|
210
|
-
{...rest}
|
|
211
|
-
>
|
|
212
|
-
<div className="popover-arrow"></div>
|
|
213
|
-
<div className="popover-header">{title}</div>
|
|
214
|
-
<div className="popover-body">{content}</div>
|
|
215
|
-
</div>
|
|
216
|
-
)}
|
|
217
|
-
</Transition>
|
|
195
|
+
{mounted && (
|
|
196
|
+
<div
|
|
197
|
+
className={classNames('popover', 'bs-popover-auto', className)}
|
|
198
|
+
id={uID.current}
|
|
199
|
+
ref={forkedRef}
|
|
200
|
+
role="tooltip"
|
|
201
|
+
style={{
|
|
202
|
+
display: 'none',
|
|
203
|
+
}}
|
|
204
|
+
{...rest}
|
|
205
|
+
>
|
|
206
|
+
<div className="popover-arrow"></div>
|
|
207
|
+
<div className="popover-header">{title}</div>
|
|
208
|
+
<div className="popover-body">{content}</div>
|
|
209
|
+
</div>
|
|
210
|
+
)}
|
|
218
211
|
</CConditionalPortal>
|
|
219
212
|
</>
|
|
220
213
|
)
|
|
@@ -6,7 +6,7 @@ import { CPopover, CButton } from '../../../index'
|
|
|
6
6
|
test('loads and displays CPopover component', async () => {
|
|
7
7
|
const { container } = render(
|
|
8
8
|
<CPopover content="A">
|
|
9
|
-
<CButton>Test</CButton>
|
|
9
|
+
<CButton color="primary">Test</CButton>
|
|
10
10
|
</CPopover>,
|
|
11
11
|
)
|
|
12
12
|
expect(container).toMatchSnapshot()
|
|
@@ -17,7 +17,7 @@ test('CPopover customize', async () => {
|
|
|
17
17
|
let arr, element
|
|
18
18
|
const { container } = render(
|
|
19
19
|
<CPopover content="content" title="title" trigger="click" placement="right">
|
|
20
|
-
<CButton>Test</CButton>
|
|
20
|
+
<CButton color="primary">Test</CButton>
|
|
21
21
|
</CPopover>,
|
|
22
22
|
{ container: document.body },
|
|
23
23
|
)
|
|
@@ -3,11 +3,33 @@
|
|
|
3
3
|
exports[`CPopover customize 1`] = `
|
|
4
4
|
<body>
|
|
5
5
|
<button
|
|
6
|
+
aria-describedby="popover744956"
|
|
6
7
|
class="btn btn-primary"
|
|
7
8
|
type="button"
|
|
8
9
|
>
|
|
9
10
|
Test
|
|
10
11
|
</button>
|
|
12
|
+
<div
|
|
13
|
+
class="popover bs-popover-auto fade show"
|
|
14
|
+
id="popover744956"
|
|
15
|
+
role="tooltip"
|
|
16
|
+
style="position: absolute; left: 0px; top: 0px; margin: 0px;"
|
|
17
|
+
>
|
|
18
|
+
<div
|
|
19
|
+
class="popover-arrow"
|
|
20
|
+
style="position: absolute;"
|
|
21
|
+
/>
|
|
22
|
+
<div
|
|
23
|
+
class="popover-header"
|
|
24
|
+
>
|
|
25
|
+
title
|
|
26
|
+
</div>
|
|
27
|
+
<div
|
|
28
|
+
class="popover-body"
|
|
29
|
+
>
|
|
30
|
+
content
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
11
33
|
</body>
|
|
12
34
|
`;
|
|
13
35
|
|
|
@@ -2,21 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`CSidebarBrand customize 1`] = `
|
|
4
4
|
<div>
|
|
5
|
-
<
|
|
5
|
+
<a
|
|
6
6
|
class="sidebar-brand bazinga"
|
|
7
7
|
>
|
|
8
8
|
Test
|
|
9
|
-
</
|
|
9
|
+
</a>
|
|
10
10
|
</div>
|
|
11
11
|
`;
|
|
12
12
|
|
|
13
13
|
exports[`loads and displays CSidebarBrand component 1`] = `
|
|
14
14
|
<div>
|
|
15
|
-
<
|
|
15
|
+
<a
|
|
16
16
|
class="sidebar-brand"
|
|
17
17
|
color="primary"
|
|
18
18
|
>
|
|
19
19
|
Test
|
|
20
|
-
</
|
|
20
|
+
</a>
|
|
21
21
|
</div>
|
|
22
22
|
`;
|
|
@@ -4,7 +4,9 @@ exports[`CSidebarNav customize 1`] = `
|
|
|
4
4
|
<div>
|
|
5
5
|
<ul
|
|
6
6
|
class="sidebar-nav bazinga"
|
|
7
|
-
|
|
7
|
+
>
|
|
8
|
+
Test
|
|
9
|
+
</ul>
|
|
8
10
|
</div>
|
|
9
11
|
`;
|
|
10
12
|
|
|
@@ -12,6 +14,8 @@ exports[`loads and displays CSidebarNav component 1`] = `
|
|
|
12
14
|
<div>
|
|
13
15
|
<ul
|
|
14
16
|
class="sidebar-nav"
|
|
15
|
-
|
|
17
|
+
>
|
|
18
|
+
Test
|
|
19
|
+
</ul>
|
|
16
20
|
</div>
|
|
17
21
|
`;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React, { forwardRef, HTMLAttributes, useContext } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import classNames from 'classnames'
|
|
4
|
+
|
|
5
|
+
import { TabsContext } from './CTabs'
|
|
6
|
+
|
|
7
|
+
export interface CTabProps extends HTMLAttributes<HTMLButtonElement> {
|
|
8
|
+
/**
|
|
9
|
+
* A string of all className you want applied to the base component.
|
|
10
|
+
*/
|
|
11
|
+
className?: string
|
|
12
|
+
/**
|
|
13
|
+
* Item key.
|
|
14
|
+
*/
|
|
15
|
+
itemKey: number | string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const CTab = forwardRef<HTMLButtonElement, CTabProps>(
|
|
19
|
+
({ children, className, itemKey, ...rest }, ref) => {
|
|
20
|
+
const { _activeItemKey, setActiveItemKey, id } = useContext(TabsContext)
|
|
21
|
+
|
|
22
|
+
const isActive = () => itemKey === _activeItemKey
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<button
|
|
26
|
+
className={classNames(
|
|
27
|
+
'nav-link',
|
|
28
|
+
{
|
|
29
|
+
active: isActive(),
|
|
30
|
+
},
|
|
31
|
+
className,
|
|
32
|
+
)}
|
|
33
|
+
id={`${id}${itemKey}-tab`}
|
|
34
|
+
onClick={() => setActiveItemKey(itemKey)}
|
|
35
|
+
onFocus={() => setActiveItemKey(itemKey)}
|
|
36
|
+
role="tab"
|
|
37
|
+
tabIndex={isActive() ? 0 : -1}
|
|
38
|
+
type="button"
|
|
39
|
+
aria-controls={`${id}${itemKey}-tab-pane`}
|
|
40
|
+
aria-selected={isActive()}
|
|
41
|
+
ref={ref}
|
|
42
|
+
{...rest}
|
|
43
|
+
>
|
|
44
|
+
{children}
|
|
45
|
+
</button>
|
|
46
|
+
)
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
CTab.propTypes = {
|
|
51
|
+
children: PropTypes.node,
|
|
52
|
+
className: PropTypes.string,
|
|
53
|
+
itemKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
CTab.displayName = 'CTab'
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import React, { forwardRef, HTMLAttributes, KeyboardEvent, useRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import classNames from 'classnames'
|
|
4
|
+
|
|
5
|
+
import { useForkedRef } from '../../hooks'
|
|
6
|
+
import { getNextActiveElement } from '../../utils'
|
|
7
|
+
|
|
8
|
+
export interface CTabListProps extends HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
/**
|
|
10
|
+
* A string of all className you want applied to the base component.
|
|
11
|
+
*/
|
|
12
|
+
className?: string
|
|
13
|
+
/**
|
|
14
|
+
* Specify a layout type for component.
|
|
15
|
+
*/
|
|
16
|
+
layout?: 'fill' | 'justified'
|
|
17
|
+
/**
|
|
18
|
+
* Set the nav variant to tabs or pills.
|
|
19
|
+
*/
|
|
20
|
+
variant?: 'pills' | 'tabs' | 'underline' | 'underline-border'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const CTabList = forwardRef<HTMLDivElement, CTabListProps>(
|
|
24
|
+
({ children, className, layout, variant, ...rest }, ref) => {
|
|
25
|
+
const tabListRef = useRef<HTMLDivElement>(null)
|
|
26
|
+
const forkedRef = useForkedRef(ref, tabListRef)
|
|
27
|
+
|
|
28
|
+
const handleKeydown = (event: KeyboardEvent<HTMLDivElement>) => {
|
|
29
|
+
if (
|
|
30
|
+
tabListRef.current !== null &&
|
|
31
|
+
(event.key === 'ArrowDown' ||
|
|
32
|
+
event.key === 'ArrowUp' ||
|
|
33
|
+
event.key === 'ArrowLeft' ||
|
|
34
|
+
event.key === 'ArrowRight' ||
|
|
35
|
+
event.key === 'Home' ||
|
|
36
|
+
event.key === 'End')
|
|
37
|
+
) {
|
|
38
|
+
event.preventDefault()
|
|
39
|
+
const target = event.target as HTMLElement
|
|
40
|
+
// eslint-disable-next-line unicorn/prefer-spread
|
|
41
|
+
const items: HTMLElement[] = Array.from(
|
|
42
|
+
tabListRef.current.querySelectorAll('.nav-link:not(.disabled):not(:disabled)'),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
let nextActiveElement
|
|
46
|
+
|
|
47
|
+
if (event.key === 'Home' || event.key === 'End') {
|
|
48
|
+
nextActiveElement = event.key === 'End' ? items.at(-1) : items[0]
|
|
49
|
+
} else {
|
|
50
|
+
nextActiveElement = getNextActiveElement(
|
|
51
|
+
items,
|
|
52
|
+
target,
|
|
53
|
+
event.key === 'ArrowDown' || event.key === 'ArrowRight',
|
|
54
|
+
true,
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (nextActiveElement) {
|
|
59
|
+
nextActiveElement.focus({ preventScroll: true })
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<div
|
|
66
|
+
className={classNames(
|
|
67
|
+
'nav',
|
|
68
|
+
{
|
|
69
|
+
[`nav-${layout}`]: layout,
|
|
70
|
+
[`nav-${variant}`]: variant,
|
|
71
|
+
},
|
|
72
|
+
className,
|
|
73
|
+
)}
|
|
74
|
+
role="tablist"
|
|
75
|
+
onKeyDown={handleKeydown}
|
|
76
|
+
ref={forkedRef}
|
|
77
|
+
{...rest}
|
|
78
|
+
>
|
|
79
|
+
{children}
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
},
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
CTabList.propTypes = {
|
|
86
|
+
children: PropTypes.node,
|
|
87
|
+
className: PropTypes.string,
|
|
88
|
+
layout: PropTypes.oneOf(['fill', 'justified']),
|
|
89
|
+
variant: PropTypes.oneOf(['pills', 'tabs', 'underline', 'underline-border']),
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
CTabList.displayName = 'CTabList'
|