@coreui/react-pro 4.11.2 → 4.12.0-alpha.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/date-range-picker/CDateRangePicker copy.d.ts +114 -0
- package/dist/components/date-range-picker/CDateRangePicker.d.ts +49 -1
- package/dist/components/multi-select/CMultiSelect.d.ts +34 -3
- package/dist/components/multi-select/CMultiSelectNativeSelect.d.ts +4 -5
- package/dist/components/multi-select/CMultiSelectOptions.d.ts +4 -2
- package/dist/components/multi-select/CMultiSelectSelection.d.ts +1 -0
- package/dist/components/multi-select/types.d.ts +7 -3
- package/dist/components/multi-select/utils.d.ts +5 -5
- package/dist/components/multi-select-new/CMultiSelect.d.ts +133 -0
- package/dist/components/multi-select-new/CMultiSelectNativeSelect.d.ts +7 -0
- package/dist/components/multi-select-new/CMultiSelectNew.d.ts +121 -0
- package/dist/components/multi-select-new/CMultiSelectOptions.d.ts +16 -0
- package/dist/components/multi-select-new/CMultiSelectSelection.d.ts +11 -0
- package/dist/components/multi-select-new/index.d.ts +2 -0
- package/dist/components/multi-select-new/types.d.ts +15 -0
- package/dist/components/multi-select-new/utils.d.ts +11 -0
- package/dist/components/picker/CPicker copy.d.ts +82 -0
- package/dist/components/picker/CPicker.d.ts +14 -56
- package/dist/components/picker copy/CPicker.d.ts +82 -0
- package/dist/components/popover/CPopover.d.ts +1 -1
- package/dist/components/time-picker/CTimePicker.d.ts +41 -1
- package/dist/components/tooltip/CTooltip.d.ts +3 -3
- package/dist/index.es.js +2200 -2074
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +2199 -2073
- 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 +7 -7
- package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +601 -555
- package/src/components/date-picker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +599 -561
- package/src/components/date-range-picker/CDateRangePicker.tsx +198 -97
- package/src/components/date-range-picker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +1197 -1121
- package/src/components/dropdown/CDropdownMenu.tsx +5 -4
- package/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap +1 -1
- package/src/components/element-cover/CElementCover.tsx +1 -0
- package/src/components/multi-select/CMultiSelect.tsx +200 -79
- package/src/components/multi-select/CMultiSelectNativeSelect.tsx +34 -24
- package/src/components/multi-select/CMultiSelectOptions.tsx +25 -23
- package/src/components/multi-select/CMultiSelectSelection.tsx +36 -7
- package/src/components/multi-select/__tests__/CMultiSelect.spec.tsx +25 -14
- package/src/components/multi-select/__tests__/CMultiSelectNativeSelect.spec.tsx +1 -1
- package/src/components/multi-select/__tests__/CMultiSelectOptions.spec.tsx +4 -4
- package/src/components/multi-select/__tests__/CMultiSelectSelection.spec.tsx +0 -1
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelect.spec.tsx.snap +136 -30
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectNativeSelect.spec.tsx.snap +2 -0
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectOptions.spec.tsx.snap +3 -1
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectSelection.spec.tsx.snap +2 -2
- package/src/components/multi-select/types.ts +9 -4
- package/src/components/multi-select/utils.ts +56 -39
- package/src/components/picker/CPicker.tsx +113 -138
- package/src/components/popover/CPopover.tsx +62 -26
- package/src/components/smart-table/CSmartTable.tsx +5 -1
- package/src/components/smart-table/__tests__/CSmartTable.spec.tsx +1 -1
- package/src/components/smart-table/__tests__/__snapshots__/CSmartTable.spec.tsx.snap +580 -0
- package/src/components/time-picker/CTimePicker.tsx +182 -82
- package/src/components/time-picker/__tests__/__snapshots__/CTimePicker.spec.tsx.snap +1078 -0
- package/src/components/tooltip/CTooltip.tsx +66 -31
- package/src/components/virtual-scroller/CVirtualScroller.tsx +0 -1
- package/src/utils/index.ts +2 -1
- package/src/utils/isRTL.ts +13 -0
- package/src/components/multi-select/__tests__/CMultiSelectCleaner.spec.tsx +0 -15
- package/src/components/multi-select/__tests__/CMultiSelectSearchInput.spec.tsx +0 -17
- package/src/components/multi-select/__tests__/CMultiSelectSelectAllButton.spec.tsx +0 -21
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectCleaner.spec.tsx.snap +0 -19
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectSearchInput.spec.tsx.snap +0 -20
- package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectSelectAllButton.spec.tsx.snap +0 -24
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { Option, SelectedOption } from './types'
|
|
1
|
+
import type { Option, OptionsGroup, SelectedOption } from './types'
|
|
2
2
|
|
|
3
|
-
export const createOption = (text: string, options: Option[]) => {
|
|
3
|
+
export const createOption = (text: string, options: (Option | OptionsGroup)[]) => {
|
|
4
4
|
const value = text.toLowerCase().replace(/\s/g, '-')
|
|
5
5
|
let uniqueValue = value
|
|
6
6
|
let i = 1
|
|
7
7
|
|
|
8
|
-
while (options.
|
|
8
|
+
while (options.some((option) => String(option.value) === uniqueValue)) {
|
|
9
9
|
uniqueValue = `${value}-${i}`
|
|
10
10
|
i++
|
|
11
11
|
}
|
|
@@ -19,32 +19,52 @@ export const createOption = (text: string, options: Option[]) => {
|
|
|
19
19
|
]
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export const filterOptionsList = (search: string, _options: Option[]) =>
|
|
23
|
-
search.length > 0
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
22
|
+
export const filterOptionsList = (search: string, _options: (Option | OptionsGroup)[]) => {
|
|
23
|
+
if (search.length > 0 && _options) {
|
|
24
|
+
const optionsList = []
|
|
25
|
+
|
|
26
|
+
for (const option of _options) {
|
|
27
|
+
const options =
|
|
28
|
+
option.options &&
|
|
29
|
+
option.options.filter(
|
|
30
|
+
(option: Option) =>
|
|
31
|
+
option.text && option.text.toLowerCase().includes(search.toLowerCase()),
|
|
32
|
+
)
|
|
33
|
+
if (
|
|
34
|
+
(option.text && option.text.toLowerCase().includes(search.toLowerCase())) ||
|
|
35
|
+
(options && options.length > 0)
|
|
36
|
+
) {
|
|
37
|
+
optionsList.push(Object.assign({}, option, options && options.length > 0 && { options }))
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return optionsList
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return _options
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const flattenOptionsArray = (
|
|
48
|
+
options: (Option | OptionsGroup)[],
|
|
49
|
+
keepGroupLabel?: boolean,
|
|
50
|
+
): (Option | OptionsGroup)[] => {
|
|
51
|
+
const optionsList: (Option | OptionsGroup)[] = []
|
|
52
|
+
|
|
53
|
+
for (const option of options) {
|
|
54
|
+
if (Array.isArray(option.options)) {
|
|
55
|
+
const { options, ...rest } = option
|
|
56
|
+
if (keepGroupLabel) {
|
|
57
|
+
optionsList.push(rest)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
optionsList.push(...options)
|
|
61
|
+
} else {
|
|
62
|
+
optionsList.push(option)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return optionsList
|
|
67
|
+
}
|
|
48
68
|
|
|
49
69
|
export const getNextSibling = (elem: HTMLElement, selector?: string) => {
|
|
50
70
|
// Get the next sibling element
|
|
@@ -81,7 +101,7 @@ export const getPreviousSibling = (elem: HTMLElement, selector?: string) => {
|
|
|
81
101
|
}
|
|
82
102
|
|
|
83
103
|
export const selectOptions = (
|
|
84
|
-
options: Option[],
|
|
104
|
+
options: (Option | OptionsGroup)[],
|
|
85
105
|
selected: SelectedOption[],
|
|
86
106
|
deselected?: Option[],
|
|
87
107
|
) => {
|
|
@@ -94,16 +114,13 @@ export const selectOptions = (
|
|
|
94
114
|
)
|
|
95
115
|
}
|
|
96
116
|
|
|
97
|
-
const deduplicated
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
...(option.disabled && { disabled: option.disabled }),
|
|
103
|
-
})
|
|
117
|
+
const deduplicated: SelectedOption[] = []
|
|
118
|
+
|
|
119
|
+
for (const option of _selected) {
|
|
120
|
+
if (!deduplicated.some((obj) => obj.value === option.value)) {
|
|
121
|
+
deduplicated.push(option as SelectedOption)
|
|
104
122
|
}
|
|
105
|
-
|
|
106
|
-
}, []) as SelectedOption[]
|
|
123
|
+
}
|
|
107
124
|
|
|
108
125
|
return deduplicated
|
|
109
126
|
}
|
|
@@ -1,63 +1,13 @@
|
|
|
1
|
-
import React, { forwardRef, ReactNode, useEffect, useState } from 'react'
|
|
1
|
+
import React, { forwardRef, HTMLAttributes, ReactNode, useEffect, useRef, useState } from 'react'
|
|
2
|
+
|
|
2
3
|
import PropTypes from 'prop-types'
|
|
3
4
|
import classNames from 'classnames'
|
|
5
|
+
import { createPopper, Instance } from '@popperjs/core'
|
|
4
6
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { CDropdownMenu } from '../dropdown/CDropdownMenu'
|
|
8
|
-
import { CDropdownToggle } from '../dropdown/CDropdownToggle'
|
|
9
|
-
|
|
10
|
-
import { Colors } from '../../types'
|
|
7
|
+
import { useForkedRef } from '../../hooks'
|
|
8
|
+
import { isRTL } from '../../utils'
|
|
11
9
|
|
|
12
|
-
export interface CPickerProps extends
|
|
13
|
-
/**
|
|
14
|
-
* Toggle visibility or set the content of cancel button.
|
|
15
|
-
*
|
|
16
|
-
* @default 'Cancel'
|
|
17
|
-
*/
|
|
18
|
-
cancelButton?: boolean | ReactNode
|
|
19
|
-
/**
|
|
20
|
-
* Sets the color context of the cancel button to one of CoreUI’s themed colors.
|
|
21
|
-
*
|
|
22
|
-
* @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
|
|
23
|
-
* @default 'primary'
|
|
24
|
-
*/
|
|
25
|
-
cancelButtonColor?: Colors
|
|
26
|
-
/**
|
|
27
|
-
* Size the cancel button small or large.
|
|
28
|
-
*
|
|
29
|
-
* @default 'sm'
|
|
30
|
-
*/
|
|
31
|
-
cancelButtonSize?: 'sm' | 'lg'
|
|
32
|
-
/**
|
|
33
|
-
* Set the cancel button variant to an outlined button or a ghost button.
|
|
34
|
-
*
|
|
35
|
-
* @default 'ghost'
|
|
36
|
-
*/
|
|
37
|
-
cancelButtonVariant?: 'outline' | 'ghost'
|
|
38
|
-
/**
|
|
39
|
-
* Toggle visibility or set the content of confirm button.
|
|
40
|
-
*
|
|
41
|
-
* @default 'OK'
|
|
42
|
-
*/
|
|
43
|
-
confirmButton?: boolean | ReactNode
|
|
44
|
-
/**
|
|
45
|
-
* Sets the color context of the confirm button to one of CoreUI’s themed colors.
|
|
46
|
-
*
|
|
47
|
-
* @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
|
|
48
|
-
* @default 'primary'
|
|
49
|
-
*/
|
|
50
|
-
confirmButtonColor?: Colors
|
|
51
|
-
/**
|
|
52
|
-
* Size the confirm button small or large.
|
|
53
|
-
*
|
|
54
|
-
* @default 'sm'
|
|
55
|
-
*/
|
|
56
|
-
confirmButtonSize?: 'sm' | 'lg'
|
|
57
|
-
/**
|
|
58
|
-
* Set the confirm button variant to an outlined button or a ghost button.
|
|
59
|
-
*/
|
|
60
|
-
confirmButtonVariant?: 'outline' | 'ghost'
|
|
10
|
+
export interface CPickerProps extends HTMLAttributes<HTMLDivElement> {
|
|
61
11
|
/**
|
|
62
12
|
* Set container type for the component.
|
|
63
13
|
*/
|
|
@@ -66,6 +16,10 @@ export interface CPickerProps extends Omit<CDropdownProps, 'variant'> {
|
|
|
66
16
|
* Toggle the disabled state for the component.
|
|
67
17
|
*/
|
|
68
18
|
disabled?: boolean
|
|
19
|
+
/**
|
|
20
|
+
* A string of all className you want applied to the dropdown menu.
|
|
21
|
+
*/
|
|
22
|
+
dropdownClassNames?: string
|
|
69
23
|
/**
|
|
70
24
|
* Toggle visibility of footer element or set the content of footer.
|
|
71
25
|
*/
|
|
@@ -75,115 +29,144 @@ export interface CPickerProps extends Omit<CDropdownProps, 'variant'> {
|
|
|
75
29
|
*/
|
|
76
30
|
footerContent?: ReactNode
|
|
77
31
|
/**
|
|
78
|
-
* Callback fired when the
|
|
32
|
+
* Callback fired when the component requests to be hidden.
|
|
79
33
|
*/
|
|
80
|
-
|
|
34
|
+
onHide?: () => void
|
|
81
35
|
/**
|
|
82
|
-
* Callback fired when the
|
|
36
|
+
* Callback fired when the component requests to be shown.
|
|
83
37
|
*/
|
|
84
|
-
|
|
38
|
+
onShow?: () => void
|
|
85
39
|
/**
|
|
86
40
|
* The content of toggler.
|
|
87
41
|
*/
|
|
88
42
|
toggler?: ReactNode
|
|
43
|
+
/**
|
|
44
|
+
* Toggle the visibility of dropdown menu component.
|
|
45
|
+
*/
|
|
46
|
+
visible?: boolean
|
|
89
47
|
}
|
|
90
48
|
|
|
91
49
|
export const CPicker = forwardRef<HTMLDivElement | HTMLLIElement, CPickerProps>(
|
|
92
50
|
(
|
|
93
51
|
{
|
|
94
52
|
children,
|
|
95
|
-
cancelButton = 'Cancel',
|
|
96
|
-
cancelButtonColor = 'primary',
|
|
97
|
-
cancelButtonSize = 'sm',
|
|
98
|
-
cancelButtonVariant = 'ghost',
|
|
99
|
-
confirmButton = 'OK',
|
|
100
|
-
confirmButtonColor = 'primary',
|
|
101
|
-
confirmButtonSize = 'sm',
|
|
102
|
-
confirmButtonVariant,
|
|
103
53
|
className,
|
|
104
54
|
container = 'dropdown',
|
|
105
55
|
disabled,
|
|
56
|
+
dropdownClassNames,
|
|
106
57
|
footer,
|
|
107
58
|
footerContent,
|
|
108
|
-
onCancel,
|
|
109
|
-
onConfirm,
|
|
110
59
|
onHide,
|
|
111
60
|
onShow,
|
|
112
|
-
toggler
|
|
61
|
+
toggler,
|
|
113
62
|
visible,
|
|
114
|
-
...rest
|
|
115
63
|
},
|
|
116
64
|
ref,
|
|
117
65
|
) => {
|
|
66
|
+
const pickerRef = useRef<HTMLDivElement>(null)
|
|
67
|
+
const pickerForkedRef = useForkedRef(ref, pickerRef)
|
|
68
|
+
const dropdownRef = useRef<HTMLDivElement>(null)
|
|
69
|
+
const togglerRef = useRef<HTMLDivElement>(null)
|
|
70
|
+
|
|
71
|
+
const popper = useRef<Instance>()
|
|
72
|
+
|
|
118
73
|
const [_visible, setVisible] = useState(visible)
|
|
119
74
|
|
|
120
75
|
useEffect(() => {
|
|
121
76
|
setVisible(visible)
|
|
122
77
|
}, [visible])
|
|
123
78
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (container !== 'inline' && _visible) {
|
|
81
|
+
onShow && onShow()
|
|
82
|
+
|
|
83
|
+
window.addEventListener('mouseup', handleMouseUp)
|
|
84
|
+
window.addEventListener('keyup', handleKeyUp)
|
|
85
|
+
|
|
86
|
+
initPopper()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return () => {
|
|
90
|
+
onHide && onHide()
|
|
91
|
+
|
|
92
|
+
window.removeEventListener('mouseup', handleMouseUp)
|
|
93
|
+
window.removeEventListener('keyup', handleKeyUp)
|
|
94
|
+
|
|
95
|
+
destroyPopper()
|
|
96
|
+
}
|
|
97
|
+
}, [_visible])
|
|
98
|
+
|
|
99
|
+
const initPopper = () => {
|
|
100
|
+
if (togglerRef.current && dropdownRef.current) {
|
|
101
|
+
popper.current = createPopper(togglerRef.current, dropdownRef.current, {
|
|
102
|
+
placement: isRTL(pickerRef.current) ? 'bottom-end' : 'bottom-start',
|
|
103
|
+
modifiers: [
|
|
104
|
+
{
|
|
105
|
+
name: 'preventOverflow',
|
|
106
|
+
options: {
|
|
107
|
+
boundary: 'clippingParents',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'offset',
|
|
112
|
+
options: {
|
|
113
|
+
offset: [0, 2],
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const destroyPopper = () => {
|
|
122
|
+
if (popper.current) {
|
|
123
|
+
popper.current.destroy()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
popper.current = undefined
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const handleKeyUp = (event: KeyboardEvent) => {
|
|
130
|
+
if (event.key === 'Escape') {
|
|
131
|
+
setVisible(false)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const handleMouseUp = (event: Event) => {
|
|
136
|
+
if (pickerRef.current && pickerRef.current.contains(event.target as HTMLElement)) {
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
setVisible(false)
|
|
141
|
+
}
|
|
152
142
|
|
|
153
143
|
switch (container) {
|
|
154
144
|
case 'inline': {
|
|
155
|
-
return
|
|
145
|
+
return (
|
|
146
|
+
<div className={classNames('picker', className)} ref={pickerForkedRef}>
|
|
147
|
+
{children}
|
|
148
|
+
</div>
|
|
149
|
+
)
|
|
156
150
|
}
|
|
157
151
|
default: {
|
|
158
152
|
return (
|
|
159
|
-
<
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}}
|
|
166
|
-
onShow={() => {
|
|
167
|
-
setVisible(true)
|
|
168
|
-
onShow && onShow()
|
|
169
|
-
}}
|
|
170
|
-
variant="dropdown"
|
|
171
|
-
visible={_visible}
|
|
172
|
-
{...rest}
|
|
173
|
-
ref={ref}
|
|
153
|
+
<div
|
|
154
|
+
className={classNames(className, {
|
|
155
|
+
show: _visible,
|
|
156
|
+
})}
|
|
157
|
+
onClick={() => !disabled && setVisible(true)}
|
|
158
|
+
ref={pickerForkedRef}
|
|
174
159
|
>
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
160
|
+
{toggler &&
|
|
161
|
+
React.isValidElement(toggler) &&
|
|
162
|
+
React.cloneElement(toggler as React.ReactElement<any>, {
|
|
163
|
+
ref: togglerRef,
|
|
164
|
+
})}
|
|
165
|
+
<div className={dropdownClassNames} ref={dropdownRef}>
|
|
179
166
|
{children}
|
|
180
|
-
{footer &&
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
</div>
|
|
184
|
-
)}
|
|
185
|
-
</CDropdownMenu>
|
|
186
|
-
</CDropdown>
|
|
167
|
+
{footer && footerContent}
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
187
170
|
)
|
|
188
171
|
}
|
|
189
172
|
}
|
|
@@ -193,22 +176,14 @@ export const CPicker = forwardRef<HTMLDivElement | HTMLLIElement, CPickerProps>(
|
|
|
193
176
|
CPicker.displayName = 'CPicker'
|
|
194
177
|
|
|
195
178
|
CPicker.propTypes = {
|
|
196
|
-
cancelButton: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
|
|
197
|
-
cancelButtonColor: CButton.propTypes?.color,
|
|
198
|
-
cancelButtonSize: CButton.propTypes?.size,
|
|
199
|
-
cancelButtonVariant: CButton.propTypes?.variant,
|
|
200
|
-
confirmButton: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
|
|
201
|
-
confirmButtonColor: CButton.propTypes?.color,
|
|
202
|
-
confirmButtonSize: CButton.propTypes?.size,
|
|
203
|
-
confirmButtonVariant: CButton.propTypes?.variant,
|
|
204
179
|
children: PropTypes.node,
|
|
205
180
|
className: PropTypes.string,
|
|
206
181
|
container: PropTypes.oneOf(['dropdown', 'inline']),
|
|
207
182
|
disabled: PropTypes.bool,
|
|
183
|
+
dropdownClassNames: PropTypes.string,
|
|
208
184
|
footer: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
|
|
209
185
|
footerContent: PropTypes.node,
|
|
210
|
-
|
|
211
|
-
|
|
186
|
+
onHide: PropTypes.func,
|
|
187
|
+
onShow: PropTypes.func,
|
|
212
188
|
toggler: PropTypes.node,
|
|
213
|
-
...CDropdown.propTypes,
|
|
214
189
|
}
|
|
@@ -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>
|
|
@@ -265,8 +265,12 @@ export const CSmartTable = forwardRef<HTMLDivElement, CSmartTableProps>(
|
|
|
265
265
|
return
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
+
const selected = _items.map((item) => {
|
|
269
|
+
return { ...item }
|
|
270
|
+
})
|
|
271
|
+
|
|
268
272
|
setSelected(
|
|
269
|
-
|
|
273
|
+
selected.map((item) => {
|
|
270
274
|
delete item['_cellProps']
|
|
271
275
|
delete item['_props']
|
|
272
276
|
delete item['_selected']
|
|
@@ -2,7 +2,7 @@ import * as React from 'react'
|
|
|
2
2
|
import { render } from '@testing-library/react'
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect'
|
|
4
4
|
import { CBadge, CSmartTable } from '../../../index'
|
|
5
|
-
import { Item } from '../
|
|
5
|
+
import { Item } from '../types'
|
|
6
6
|
|
|
7
7
|
test('loads and displays CSpinner component', async () => {
|
|
8
8
|
const columns = [
|