@coreui/react-pro 4.1.4 → 4.2.0-rc.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/Types.d.ts +1 -1
- package/dist/components/accordion/index.d.ts +7 -0
- package/dist/components/alert/index.d.ts +4 -0
- package/dist/components/avatar/index.d.ts +2 -0
- package/dist/components/backdrop/index.d.ts +2 -0
- package/dist/components/badge/index.d.ts +2 -0
- package/dist/components/breadcrumb/index.d.ts +3 -0
- package/dist/components/button/index.d.ts +2 -0
- package/dist/components/button-group/index.d.ts +3 -0
- package/dist/components/calendar/CCalendar.d.ts +113 -0
- package/dist/components/callout/index.d.ts +2 -0
- package/dist/components/card/index.d.ts +12 -0
- package/dist/components/carousel/index.d.ts +4 -0
- package/dist/components/close-button/index.d.ts +2 -0
- package/dist/components/collapse/index.d.ts +2 -0
- package/dist/components/datepicker/CDatePicker.d.ts +13 -0
- package/dist/components/datepicker/index.d.ts +2 -0
- package/dist/components/daterangepicker/CDateRangePicker.d.ts +65 -0
- package/dist/components/daterangepicker/index.d.ts +2 -0
- package/dist/components/dropdown/CDropdown.d.ts +10 -1
- package/dist/components/dropdown/CDropdownToggle.d.ts +4 -0
- package/dist/components/dropdown/index.d.ts +8 -0
- package/dist/components/footer/index.d.ts +2 -0
- package/dist/components/form/CForm.d.ts +2 -2
- package/dist/components/form/CFormCheck.d.ts +2 -1
- package/dist/components/form/CFormControlValidation.d.ts +46 -0
- package/dist/components/form/CFormControlWrapper.d.ts +31 -0
- package/dist/components/form/CFormInput.d.ts +2 -9
- package/dist/components/form/CFormRange.d.ts +7 -1
- package/dist/components/form/CFormSelect.d.ts +3 -10
- package/dist/components/form/CFormTextarea.d.ts +2 -9
- package/dist/components/form/index.d.ts +14 -0
- package/dist/components/grid/index.d.ts +4 -0
- package/dist/components/header/index.d.ts +7 -0
- package/dist/components/image/index.d.ts +2 -0
- package/dist/components/index.d.ts +41 -0
- package/dist/components/link/index.d.ts +2 -0
- package/dist/components/list-group/index.d.ts +3 -0
- package/dist/components/loading-button/index.d.ts +2 -0
- package/dist/components/modal/CModal.d.ts +3 -0
- package/dist/components/modal/index.d.ts +8 -0
- package/dist/components/multi-select/index.d.ts +2 -0
- package/dist/components/nav/index.d.ts +7 -0
- package/dist/components/navbar/index.d.ts +6 -0
- package/dist/components/offcanvas/index.d.ts +5 -0
- package/dist/components/pagination/index.d.ts +4 -0
- package/dist/components/picker/CPicker.d.ts +78 -0
- package/dist/components/placeholder/index.d.ts +2 -0
- package/dist/components/popover/CPopover.d.ts +2 -2
- package/dist/components/popover/index.d.ts +2 -0
- package/dist/components/progress/index.d.ts +3 -0
- package/dist/components/sidebar/index.d.ts +7 -0
- package/dist/components/smart-table/index.d.ts +2 -0
- package/dist/components/spinner/index.d.ts +2 -0
- package/dist/components/table/index.d.ts +9 -0
- package/dist/components/tabs/index.d.ts +3 -0
- package/dist/components/timepicker/CTimePicker.d.ts +45 -0
- package/dist/components/timepicker/CTimePickerRollCol.d.ts +11 -0
- package/dist/components/timepicker/index.d.ts +2 -0
- package/dist/components/toast/index.d.ts +6 -0
- package/dist/components/tooltip/CTooltip.d.ts +2 -2
- package/dist/components/tooltip/index.d.ts +2 -0
- package/dist/index.d.ts +0 -125
- package/dist/index.es.js +3268 -1339
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +3513 -1582
- package/dist/index.js.map +1 -1
- package/dist/utils/calendar.d.ts +23 -0
- package/dist/utils/hooks/useStateWithCallback.d.ts +2 -1
- package/dist/utils/time.d.ts +21 -0
- package/package.json +12 -11
- package/src/components/Types.tsx +2 -2
- package/src/components/accordion/CAccordionButton.tsx +2 -1
- package/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.tsx.snap +2 -0
- package/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.tsx.snap +2 -0
- package/src/components/accordion/index.ts +15 -0
- package/src/components/alert/CAlert.tsx +14 -3
- package/src/components/alert/index.ts +5 -0
- package/src/components/avatar/index.ts +3 -0
- package/src/components/backdrop/CBackdrop.tsx +10 -3
- package/src/components/backdrop/index.ts +3 -0
- package/src/components/badge/index.ts +3 -0
- package/src/components/breadcrumb/index.ts +4 -0
- package/src/components/button/index.ts +3 -0
- package/src/components/button-group/index.ts +4 -0
- package/src/components/calendar/CCalendar.tsx +559 -0
- package/src/components/calendar/__tests__/CCalendar.spec.tsx +9 -0
- package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +573 -0
- package/src/components/callout/index.ts +3 -0
- package/src/components/card/index.ts +25 -0
- package/src/components/carousel/index.ts +5 -0
- package/src/components/close-button/index.ts +3 -0
- package/src/components/collapse/CCollapse.tsx +1 -0
- package/src/components/collapse/index.ts +3 -0
- package/src/components/datepicker/CDatePicker.tsx +50 -0
- package/src/components/datepicker/__tests__/CDatePicker.spec.tsx +9 -0
- package/src/components/datepicker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +617 -0
- package/src/components/datepicker/index.ts +3 -0
- package/src/components/daterangepicker/CDateRangePicker.tsx +432 -0
- package/src/components/daterangepicker/__tests__/CDateRangePicker.spec.tsx +9 -0
- package/src/components/daterangepicker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +1201 -0
- package/src/components/daterangepicker/index.ts +3 -0
- package/src/components/dropdown/CDropdown.tsx +19 -24
- package/src/components/dropdown/CDropdownItem.tsx +1 -1
- package/src/components/dropdown/CDropdownMenu.tsx +55 -3
- package/src/components/dropdown/CDropdownToggle.tsx +28 -5
- package/src/components/dropdown/index.ts +17 -0
- package/src/components/footer/index.ts +3 -0
- package/src/components/form/CForm.tsx +2 -2
- package/src/components/form/CFormCheck.tsx +32 -7
- package/src/components/form/CFormControlValidation.tsx +97 -0
- package/src/components/form/CFormControlWrapper.tsx +85 -0
- package/src/components/form/CFormInput.tsx +47 -18
- package/src/components/form/CFormRange.tsx +18 -4
- package/src/components/form/CFormSelect.tsx +60 -32
- package/src/components/form/CFormTextarea.tsx +45 -17
- package/src/components/form/index.ts +29 -0
- package/src/components/grid/index.ts +5 -0
- package/src/components/header/index.ts +8 -0
- package/src/components/image/index.ts +3 -0
- package/src/components/index.ts +41 -0
- package/src/components/link/index.ts +3 -0
- package/src/components/list-group/index.ts +4 -0
- package/src/components/loading-button/index.ts +3 -0
- package/src/components/modal/CModal.tsx +3 -2
- package/src/components/modal/index.ts +9 -0
- package/src/components/multi-select/CMultiSelect.tsx +45 -38
- package/src/components/multi-select/index.ts +3 -0
- package/src/components/nav/CNavGroup.tsx +1 -0
- package/src/components/nav/index.ts +8 -0
- package/src/components/navbar/index.ts +7 -0
- package/src/components/offcanvas/COffcanvas.tsx +1 -0
- package/src/components/offcanvas/index.ts +6 -0
- package/src/components/pagination/index.ts +5 -0
- package/src/components/picker/CPicker.tsx +207 -0
- package/src/components/picker/__tests__/CPicker.spec.tsx +9 -0
- package/src/components/picker/__tests__/__snapshots__/CPicker.spec.tsx.snap +23 -0
- package/src/components/placeholder/index.ts +3 -0
- package/src/components/popover/CPopover.tsx +78 -70
- package/src/components/popover/index.ts +3 -0
- package/src/components/progress/index.ts +4 -0
- package/src/components/sidebar/index.ts +8 -0
- package/src/components/smart-table/index.ts +3 -0
- package/src/components/spinner/index.ts +3 -0
- package/src/components/table/index.ts +19 -0
- package/src/components/tabs/CTabPane.tsx +7 -3
- package/src/components/tabs/index.ts +4 -0
- package/src/components/timepicker/CTimePicker.tsx +313 -0
- package/src/components/timepicker/CTimePickerRollCol.tsx +63 -0
- package/src/components/timepicker/__tests__/CTimePicker.spec.tsx +9 -0
- package/src/components/timepicker/index.ts +3 -0
- package/src/components/toast/CToast.tsx +6 -1
- package/src/components/toast/index.ts +7 -0
- package/src/components/tooltip/CTooltip.tsx +68 -60
- package/src/components/tooltip/index.ts +3 -0
- package/src/index.ts +0 -252
- package/src/utils/calendar.ts +270 -0
- package/src/utils/hooks/useStateWithCallback.ts +6 -3
- package/src/utils/time.ts +84 -0
- package/dist/components/dropdown/CDropdownToggleCustom.d.ts +0 -15
- package/src/components/dropdown/CDropdownToggleCustom.tsx +0 -81
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/* eslint-disable react/prop-types */
|
|
2
|
+
import React, { forwardRef, ReactNode, useEffect, useRef, useState } from 'react'
|
|
3
|
+
import PropTypes from 'prop-types'
|
|
4
|
+
import classNames from 'classnames'
|
|
5
|
+
|
|
6
|
+
import { CFormInput } from '../form/CFormInput'
|
|
7
|
+
import { CFormSelect } from '../form/CFormSelect'
|
|
8
|
+
import { CInputGroup } from '../form/CInputGroup'
|
|
9
|
+
import { CInputGroupText } from '../form/CInputGroupText'
|
|
10
|
+
|
|
11
|
+
import { CTimePickerRollCol } from './CTimePickerRollCol'
|
|
12
|
+
import { CPicker, CPickerProps } from './../picker/CPicker'
|
|
13
|
+
import {
|
|
14
|
+
convert12hTo24h,
|
|
15
|
+
convertTimeToDate,
|
|
16
|
+
getAmPm,
|
|
17
|
+
getListOfHours,
|
|
18
|
+
getListOfMinutes,
|
|
19
|
+
getListOfSeconds,
|
|
20
|
+
getSelectedHour,
|
|
21
|
+
getSelectedMinutes,
|
|
22
|
+
getSelectedSeconds,
|
|
23
|
+
isAmPm,
|
|
24
|
+
isValidTime,
|
|
25
|
+
} from '../../utils/time'
|
|
26
|
+
|
|
27
|
+
export interface CTimePickerProps
|
|
28
|
+
extends Omit<
|
|
29
|
+
CPickerProps,
|
|
30
|
+
'autoClose' | 'component' | 'dark' | 'placeholder' | 'variant' | 'onChange'
|
|
31
|
+
> {
|
|
32
|
+
/**
|
|
33
|
+
* A string of all className you want applied to the component.
|
|
34
|
+
*/
|
|
35
|
+
className?: string
|
|
36
|
+
/**
|
|
37
|
+
* Toggle visibility or set the content of the cleaner button.
|
|
38
|
+
*/
|
|
39
|
+
cleaner?: ReactNode | boolean
|
|
40
|
+
/**
|
|
41
|
+
* Toggle visibility or set the content of the input indicator.
|
|
42
|
+
*/
|
|
43
|
+
indicator?: ReactNode | boolean
|
|
44
|
+
/**
|
|
45
|
+
* Toggle the readonly state for the component.
|
|
46
|
+
*/
|
|
47
|
+
inputReadOnly?: boolean
|
|
48
|
+
/**
|
|
49
|
+
* Sets the default locale for components. If not set, it is inherited from the browser.
|
|
50
|
+
*/
|
|
51
|
+
locale?: string
|
|
52
|
+
/**
|
|
53
|
+
* Callback fired when the time changed.
|
|
54
|
+
*/
|
|
55
|
+
onTimeChange?: (timeString: string, localeTimeString: string, date: Date) => void
|
|
56
|
+
/**
|
|
57
|
+
* Specifies a short hint that is visible in the input.
|
|
58
|
+
*/
|
|
59
|
+
placeholder?: string
|
|
60
|
+
/**
|
|
61
|
+
* Size the component small or large.
|
|
62
|
+
*/
|
|
63
|
+
size?: 'sm' | 'lg'
|
|
64
|
+
/**
|
|
65
|
+
* Initial selected time.
|
|
66
|
+
*/
|
|
67
|
+
time?: Date | string | null
|
|
68
|
+
/**
|
|
69
|
+
* Set the time picker variant to a roll or select.
|
|
70
|
+
*/
|
|
71
|
+
variant?: 'roll' | 'select'
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePickerProps>(
|
|
75
|
+
(
|
|
76
|
+
{
|
|
77
|
+
className,
|
|
78
|
+
cleaner = true,
|
|
79
|
+
container = 'dropdown',
|
|
80
|
+
disabled,
|
|
81
|
+
footer = true,
|
|
82
|
+
indicator = true,
|
|
83
|
+
inputReadOnly,
|
|
84
|
+
locale = 'default',
|
|
85
|
+
onTimeChange,
|
|
86
|
+
onHide,
|
|
87
|
+
onShow,
|
|
88
|
+
placeholder = 'Select time',
|
|
89
|
+
size,
|
|
90
|
+
time,
|
|
91
|
+
variant = 'roll',
|
|
92
|
+
...rest
|
|
93
|
+
},
|
|
94
|
+
ref,
|
|
95
|
+
) => {
|
|
96
|
+
const inputRef = useRef<HTMLInputElement>(null)
|
|
97
|
+
const [date, setDate] = useState<Date | null>(convertTimeToDate(time))
|
|
98
|
+
const [initialDate, setInitialDate] = useState<Date | null>(null)
|
|
99
|
+
const [_ampm, setAmPm] = useState<'am' | 'pm'>(date ? getAmPm(new Date(date), locale) : 'am')
|
|
100
|
+
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
setDate(convertTimeToDate(time))
|
|
103
|
+
}, [time])
|
|
104
|
+
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (inputRef.current) {
|
|
107
|
+
inputRef.current.value = date ? date.toLocaleTimeString(locale) : ''
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
date && setAmPm(getAmPm(new Date(date), locale))
|
|
111
|
+
}, [date])
|
|
112
|
+
|
|
113
|
+
const handleClear = (event: React.MouseEvent<HTMLElement>) => {
|
|
114
|
+
event.stopPropagation()
|
|
115
|
+
setDate(null)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const handleTimeChange = (set: 'hours' | 'minutes' | 'seconds' | 'toggle', value: string) => {
|
|
119
|
+
const _date = date || new Date('1970-01-01')
|
|
120
|
+
|
|
121
|
+
if (set === 'toggle') {
|
|
122
|
+
if (value === 'am') {
|
|
123
|
+
_date.setHours(_date.getHours() - 12)
|
|
124
|
+
}
|
|
125
|
+
if (value === 'pm') {
|
|
126
|
+
_date.setHours(_date.getHours() + 12)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (set === 'hours') {
|
|
131
|
+
if (isAmPm(locale)) {
|
|
132
|
+
_date.setHours(convert12hTo24h(_ampm, parseInt(value)))
|
|
133
|
+
} else {
|
|
134
|
+
_date.setHours(parseInt(value))
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (set === 'minutes') {
|
|
139
|
+
_date.setMinutes(parseInt(value))
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (set === 'seconds') {
|
|
143
|
+
_date.setSeconds(parseInt(value))
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
setDate(new Date(_date))
|
|
147
|
+
onTimeChange && onTimeChange(_date.toTimeString(), _date.toLocaleTimeString(), _date)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const InputGroup = () => (
|
|
151
|
+
<CInputGroup className="picker-input-group" size={size}>
|
|
152
|
+
<CFormInput
|
|
153
|
+
disabled={disabled}
|
|
154
|
+
onChange={(event) =>
|
|
155
|
+
isValidTime(event.target.value) && setDate(convertTimeToDate(event.target.value))
|
|
156
|
+
}
|
|
157
|
+
placeholder={placeholder}
|
|
158
|
+
readOnly={inputReadOnly}
|
|
159
|
+
ref={inputRef}
|
|
160
|
+
/>
|
|
161
|
+
{(indicator || cleaner) && (
|
|
162
|
+
<CInputGroupText>
|
|
163
|
+
{indicator && (
|
|
164
|
+
<span className="picker-input-group-indicator">
|
|
165
|
+
{typeof indicator === 'boolean' ? (
|
|
166
|
+
<span className="picker-input-group-icon time-picker-input-icon" />
|
|
167
|
+
) : (
|
|
168
|
+
indicator
|
|
169
|
+
)}
|
|
170
|
+
</span>
|
|
171
|
+
)}
|
|
172
|
+
{cleaner && date && (
|
|
173
|
+
<span
|
|
174
|
+
className="picker-input-group-cleaner"
|
|
175
|
+
role="button"
|
|
176
|
+
onClick={(event) => handleClear(event)}
|
|
177
|
+
>
|
|
178
|
+
{typeof cleaner === 'boolean' ? (
|
|
179
|
+
<span className="picker-input-group-icon time-picker-cleaner-icon" />
|
|
180
|
+
) : (
|
|
181
|
+
cleaner
|
|
182
|
+
)}
|
|
183
|
+
</span>
|
|
184
|
+
)}
|
|
185
|
+
</CInputGroupText>
|
|
186
|
+
)}
|
|
187
|
+
</CInputGroup>
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
const TimePickerSelect = () => {
|
|
191
|
+
return (
|
|
192
|
+
<>
|
|
193
|
+
<span className="time-picker-inline-icon" />
|
|
194
|
+
<CFormSelect
|
|
195
|
+
disabled={disabled}
|
|
196
|
+
options={getListOfHours(locale).map((option) => {
|
|
197
|
+
return {
|
|
198
|
+
value: option.value.toString(),
|
|
199
|
+
label: option.label,
|
|
200
|
+
}
|
|
201
|
+
})}
|
|
202
|
+
onChange={(event: React.ChangeEvent<HTMLSelectElement>) =>
|
|
203
|
+
handleTimeChange('hours', event.target.value)
|
|
204
|
+
}
|
|
205
|
+
value={getSelectedHour(date, locale)}
|
|
206
|
+
/>
|
|
207
|
+
<>:</>
|
|
208
|
+
<CFormSelect
|
|
209
|
+
disabled={disabled}
|
|
210
|
+
// @ts-expect-error the getListOfMinutes function returns corect type
|
|
211
|
+
options={getListOfMinutes(locale, true)}
|
|
212
|
+
onChange={(event: React.ChangeEvent<HTMLSelectElement>) =>
|
|
213
|
+
handleTimeChange('minutes', event.target.value)
|
|
214
|
+
}
|
|
215
|
+
value={getSelectedMinutes(date)}
|
|
216
|
+
/>
|
|
217
|
+
<>:</>
|
|
218
|
+
<CFormSelect
|
|
219
|
+
disabled={disabled}
|
|
220
|
+
// @ts-expect-error the getListOfSeconds function returns corect type
|
|
221
|
+
options={getListOfSeconds(locale, true)}
|
|
222
|
+
onChange={(event: React.ChangeEvent<HTMLSelectElement>) =>
|
|
223
|
+
handleTimeChange('seconds', event.target.value)
|
|
224
|
+
}
|
|
225
|
+
value={getSelectedSeconds(date)}
|
|
226
|
+
/>
|
|
227
|
+
{isAmPm(locale) && (
|
|
228
|
+
<CFormSelect
|
|
229
|
+
disabled={disabled}
|
|
230
|
+
options={[
|
|
231
|
+
{ value: 'am', label: 'AM' },
|
|
232
|
+
{ value: 'pm', label: 'PM' },
|
|
233
|
+
]}
|
|
234
|
+
onChange={(event: React.ChangeEvent<HTMLSelectElement>) =>
|
|
235
|
+
handleTimeChange('toggle', event.target.value)
|
|
236
|
+
}
|
|
237
|
+
value={_ampm}
|
|
238
|
+
/>
|
|
239
|
+
)}
|
|
240
|
+
</>
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const TimePickerRoll = () => (
|
|
245
|
+
<>
|
|
246
|
+
<CTimePickerRollCol
|
|
247
|
+
elements={getListOfHours(locale)}
|
|
248
|
+
onClick={(index: number) => handleTimeChange('hours', index.toString())}
|
|
249
|
+
selected={getSelectedHour(date, locale)}
|
|
250
|
+
/>
|
|
251
|
+
<CTimePickerRollCol
|
|
252
|
+
elements={getListOfMinutes(locale)}
|
|
253
|
+
onClick={(index: number) => handleTimeChange('minutes', index.toString())}
|
|
254
|
+
selected={getSelectedMinutes(date)}
|
|
255
|
+
/>
|
|
256
|
+
<CTimePickerRollCol
|
|
257
|
+
elements={getListOfSeconds(locale)}
|
|
258
|
+
onClick={(index: number) => handleTimeChange('seconds', index.toString())}
|
|
259
|
+
selected={getSelectedSeconds(date)}
|
|
260
|
+
/>
|
|
261
|
+
{isAmPm(locale) && (
|
|
262
|
+
<CTimePickerRollCol
|
|
263
|
+
elements={[
|
|
264
|
+
{ value: 'am', label: 'AM' },
|
|
265
|
+
{ value: 'pm', label: 'PM' },
|
|
266
|
+
]}
|
|
267
|
+
onClick={(value: string) => handleTimeChange('toggle', value)}
|
|
268
|
+
selected={_ampm}
|
|
269
|
+
/>
|
|
270
|
+
)}
|
|
271
|
+
</>
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
const _className = classNames('time-picker', className)
|
|
275
|
+
|
|
276
|
+
return (
|
|
277
|
+
<CPicker
|
|
278
|
+
className={_className}
|
|
279
|
+
container={container}
|
|
280
|
+
disabled={disabled}
|
|
281
|
+
footer={footer}
|
|
282
|
+
onCancel={() => initialDate && setDate(new Date(initialDate))}
|
|
283
|
+
onHide={() => onHide && onHide()}
|
|
284
|
+
onShow={() => {
|
|
285
|
+
date && setInitialDate(new Date(date))
|
|
286
|
+
onShow && onShow()
|
|
287
|
+
}}
|
|
288
|
+
toggler={InputGroup()}
|
|
289
|
+
{...rest}
|
|
290
|
+
ref={ref}
|
|
291
|
+
>
|
|
292
|
+
<div
|
|
293
|
+
className={classNames('time-picker-body', {
|
|
294
|
+
['time-picker-roll']: variant === 'roll',
|
|
295
|
+
})}
|
|
296
|
+
>
|
|
297
|
+
{variant === 'select' ? <TimePickerSelect /> : TimePickerRoll()}
|
|
298
|
+
</div>
|
|
299
|
+
</CPicker>
|
|
300
|
+
)
|
|
301
|
+
},
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
CTimePicker.propTypes = {
|
|
305
|
+
...CPicker.propTypes,
|
|
306
|
+
className: PropTypes.string,
|
|
307
|
+
locale: PropTypes.string,
|
|
308
|
+
onTimeChange: PropTypes.func,
|
|
309
|
+
time: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
|
|
310
|
+
variant: PropTypes.oneOf(['roll', 'select']),
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
CTimePicker.displayName = 'CTimePicker'
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React, { forwardRef, useEffect, useRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import classNames from 'classnames'
|
|
4
|
+
|
|
5
|
+
import { useForkedRef } from '../../utils/hooks'
|
|
6
|
+
|
|
7
|
+
export interface Element {
|
|
8
|
+
value: number | string
|
|
9
|
+
label: number | string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CTimePickerRollColProps {
|
|
13
|
+
elements: Element[]
|
|
14
|
+
onClick?: (value: number | string) => void
|
|
15
|
+
selected?: number | string | null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const CTimePickerRollCol = forwardRef<HTMLDivElement, CTimePickerRollColProps>(
|
|
19
|
+
({ elements, onClick, selected }, ref) => {
|
|
20
|
+
const init = useRef(true)
|
|
21
|
+
const colRef = useRef<HTMLDivElement>(null)
|
|
22
|
+
const forkedRef = useForkedRef(ref, colRef)
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const nodeEl = colRef.current?.querySelector('.selected')
|
|
26
|
+
if (nodeEl && nodeEl instanceof HTMLElement) {
|
|
27
|
+
colRef.current?.scrollTo({
|
|
28
|
+
top: nodeEl.offsetTop,
|
|
29
|
+
behavior: init.current ? 'auto' : 'smooth',
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
init.current = false
|
|
34
|
+
}, [selected])
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div className="time-picker-roll-col" ref={forkedRef}>
|
|
38
|
+
{elements.map((element, index) => {
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
className={classNames('time-picker-roll-cell', {
|
|
42
|
+
selected: element.value === selected,
|
|
43
|
+
})}
|
|
44
|
+
key={index}
|
|
45
|
+
onClick={() => onClick && onClick(element.value)}
|
|
46
|
+
role="button"
|
|
47
|
+
>
|
|
48
|
+
{element.label}
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
})}
|
|
52
|
+
</div>
|
|
53
|
+
)
|
|
54
|
+
},
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
CTimePickerRollCol.propTypes = {
|
|
58
|
+
elements: PropTypes.array.isRequired,
|
|
59
|
+
onClick: PropTypes.func,
|
|
60
|
+
selected: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
CTimePickerRollCol.displayName = 'CTimePickerRollCol'
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import '@testing-library/jest-dom/extend-expect'
|
|
4
|
+
import { CTimePicker } from '../CTimePicker'
|
|
5
|
+
|
|
6
|
+
test('loads and displays CTimePicker component', async () => {
|
|
7
|
+
const { container } = render(<CTimePicker />)
|
|
8
|
+
expect(container).toMatchSnapshot()
|
|
9
|
+
})
|
|
@@ -12,6 +12,8 @@ import classNames from 'classnames'
|
|
|
12
12
|
|
|
13
13
|
import { Colors, colorPropType } from '../Types'
|
|
14
14
|
|
|
15
|
+
import { useForkedRef } from '../../utils/hooks'
|
|
16
|
+
|
|
15
17
|
export interface CToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
16
18
|
/**
|
|
17
19
|
* Apply a CSS fade transition to the toast.
|
|
@@ -82,6 +84,8 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
|
|
|
82
84
|
},
|
|
83
85
|
ref,
|
|
84
86
|
) => {
|
|
87
|
+
const toastRef = useRef()
|
|
88
|
+
const forkedRef = useForkedRef(ref, toastRef)
|
|
85
89
|
const [_visible, setVisible] = useState(false)
|
|
86
90
|
const timeout = useRef<number>()
|
|
87
91
|
|
|
@@ -133,6 +137,7 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
|
|
|
133
137
|
return (
|
|
134
138
|
<Transition
|
|
135
139
|
in={_visible}
|
|
140
|
+
nodeRef={toastRef}
|
|
136
141
|
onEnter={() => onShow && onShow(index ? index : null)}
|
|
137
142
|
onExited={() => onClose && onClose(index ? index : null)}
|
|
138
143
|
timeout={250}
|
|
@@ -151,7 +156,7 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
|
|
|
151
156
|
onMouseLeave={() => _autohide}
|
|
152
157
|
{...rest}
|
|
153
158
|
key={key}
|
|
154
|
-
ref={
|
|
159
|
+
ref={forkedRef}
|
|
155
160
|
>
|
|
156
161
|
{children}
|
|
157
162
|
</div>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CToast } from './CToast'
|
|
2
|
+
import { CToastBody } from './CToastBody'
|
|
3
|
+
import { CToastClose } from './CToastClose'
|
|
4
|
+
import { CToastHeader } from './CToastHeader'
|
|
5
|
+
import { CToaster } from './CToaster'
|
|
6
|
+
|
|
7
|
+
export { CToast, CToastBody, CToastClose, CToastHeader, CToaster }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { FC,
|
|
1
|
+
import React, { FC, ReactNode, useRef, useState } from 'react'
|
|
2
2
|
import { createPortal } from 'react-dom'
|
|
3
3
|
import PropTypes from 'prop-types'
|
|
4
4
|
import classNames from 'classnames'
|
|
@@ -9,7 +9,7 @@ import { Transition } from 'react-transition-group'
|
|
|
9
9
|
import { Triggers, triggerPropType } from '../Types'
|
|
10
10
|
|
|
11
11
|
export interface CTooltipProps {
|
|
12
|
-
children:
|
|
12
|
+
children: any
|
|
13
13
|
/**
|
|
14
14
|
* Content node for your component.
|
|
15
15
|
*/
|
|
@@ -48,6 +48,7 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
48
48
|
visible,
|
|
49
49
|
...rest
|
|
50
50
|
}) => {
|
|
51
|
+
const tooltipRef = useRef()
|
|
51
52
|
const [_visible, setVisible] = useState(visible)
|
|
52
53
|
|
|
53
54
|
const getTransitionClass = (state: string) => {
|
|
@@ -62,64 +63,71 @@ export const CTooltip: FC<CTooltipProps> = ({
|
|
|
62
63
|
|
|
63
64
|
return (
|
|
64
65
|
<Manager>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
66
|
+
<>
|
|
67
|
+
<Reference>
|
|
68
|
+
{({ ref }) =>
|
|
69
|
+
React.cloneElement(children, {
|
|
70
|
+
ref: ref,
|
|
71
|
+
...((trigger === 'click' || trigger.includes('click')) && {
|
|
72
|
+
onClick: () => setVisible(!_visible),
|
|
73
|
+
}),
|
|
74
|
+
...((trigger === 'focus' || trigger.includes('focus')) && {
|
|
75
|
+
onFocus: () => setVisible(true),
|
|
76
|
+
onBlur: () => setVisible(false),
|
|
77
|
+
}),
|
|
78
|
+
...((trigger === 'hover' || trigger.includes('hover')) && {
|
|
79
|
+
onMouseEnter: () => setVisible(true),
|
|
80
|
+
onMouseLeave: () => setVisible(false),
|
|
81
|
+
}),
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
</Reference>
|
|
85
|
+
{typeof window !== 'undefined' &&
|
|
86
|
+
createPortal(
|
|
87
|
+
<Transition
|
|
88
|
+
in={_visible}
|
|
89
|
+
mountOnEnter
|
|
90
|
+
nodeRef={tooltipRef}
|
|
91
|
+
onEnter={onShow}
|
|
92
|
+
onExit={onHide}
|
|
93
|
+
timeout={{
|
|
94
|
+
enter: 0,
|
|
95
|
+
exit: 200,
|
|
96
|
+
}}
|
|
97
|
+
unmountOnExit
|
|
98
|
+
>
|
|
99
|
+
{(state) => {
|
|
100
|
+
const transitionClass = getTransitionClass(state)
|
|
101
|
+
return (
|
|
102
|
+
<Popper placement={placement}>
|
|
103
|
+
{({ arrowProps, style, ref }) => (
|
|
104
|
+
<div
|
|
105
|
+
className={classNames(
|
|
106
|
+
`tooltip bs-tooltip-${
|
|
107
|
+
placement === 'left'
|
|
108
|
+
? 'start'
|
|
109
|
+
: placement === 'right'
|
|
110
|
+
? 'end'
|
|
111
|
+
: placement
|
|
112
|
+
}`,
|
|
113
|
+
transitionClass,
|
|
114
|
+
)}
|
|
115
|
+
ref={ref}
|
|
116
|
+
role="tooltip"
|
|
117
|
+
style={style}
|
|
118
|
+
{...rest}
|
|
119
|
+
>
|
|
120
|
+
<div className="tooltip-arrow" {...arrowProps}></div>
|
|
121
|
+
<div className="tooltip-inner">{content}</div>
|
|
122
|
+
</div>
|
|
123
|
+
)}
|
|
124
|
+
</Popper>
|
|
125
|
+
)
|
|
126
|
+
}}
|
|
127
|
+
</Transition>,
|
|
128
|
+
document.body,
|
|
129
|
+
)}
|
|
130
|
+
</>
|
|
123
131
|
</Manager>
|
|
124
132
|
)
|
|
125
133
|
}
|