@coreui/react-pro 4.11.3 → 4.12.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/calendar/CCalendar.d.ts +4 -4
- 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/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 +2385 -2403
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +2386 -2401
- 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 +15 -15
- package/src/components/accordion/index.ts +1 -7
- package/src/components/calendar/CCalendar.tsx +49 -64
- package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +601 -555
- package/src/components/calendar/utils.ts +1 -1
- package/src/components/date-picker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +599 -561
- package/src/components/date-range-picker/CDateRangePicker.tsx +208 -107
- package/src/components/date-range-picker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +1197 -1121
- package/src/components/date-range-picker/utils.ts +2 -2
- 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/form/CFormSelect.tsx +3 -1
- package/src/components/modal/CModal.tsx +2 -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 +61 -26
- 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/smart-table/CSmartTable.tsx +22 -10
- package/src/components/smart-table/CSmartTableBody.tsx +3 -5
- package/src/components/smart-table/CSmartTableHead.tsx +5 -6
- 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/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/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 +65 -31
- package/src/components/tooltip/__tests__/CTooltip.spec.tsx +1 -1
- package/src/components/virtual-scroller/CVirtualScroller.tsx +0 -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/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
- package/src/components/smart-table/CSmartTableCleaner.tsx +0 -37
|
@@ -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,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 (
|
|
@@ -111,7 +111,7 @@ export const CSidebar = forwardRef<HTMLDivElement, CSidebarProps>(
|
|
|
111
111
|
sidebarRef.current && setMobile(isOnMobile(sidebarRef.current))
|
|
112
112
|
sidebarRef.current && setInViewport(isInViewport(sidebarRef.current))
|
|
113
113
|
|
|
114
|
-
window.addEventListener('resize',
|
|
114
|
+
window.addEventListener('resize', handleResize)
|
|
115
115
|
window.addEventListener('mouseup', handleClickOutside)
|
|
116
116
|
window.addEventListener('keyup', handleKeyup)
|
|
117
117
|
|
|
@@ -121,7 +121,7 @@ export const CSidebar = forwardRef<HTMLDivElement, CSidebarProps>(
|
|
|
121
121
|
})
|
|
122
122
|
|
|
123
123
|
return () => {
|
|
124
|
-
window.removeEventListener('resize',
|
|
124
|
+
window.removeEventListener('resize', handleResize)
|
|
125
125
|
window.removeEventListener('mouseup', handleClickOutside)
|
|
126
126
|
window.removeEventListener('keyup', handleKeyup)
|
|
127
127
|
|