@coreui/react-pro 4.2.0-beta.0 → 4.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.
Files changed (163) hide show
  1. package/README.md +1 -1
  2. package/dist/components/accordion/index.d.ts +7 -0
  3. package/dist/components/alert/index.d.ts +4 -0
  4. package/dist/components/avatar/index.d.ts +2 -0
  5. package/dist/components/backdrop/index.d.ts +2 -0
  6. package/dist/components/badge/index.d.ts +2 -0
  7. package/dist/components/breadcrumb/index.d.ts +3 -0
  8. package/dist/components/button/index.d.ts +2 -0
  9. package/dist/components/button-group/index.d.ts +3 -0
  10. package/dist/components/calendar/CCalendar.d.ts +36 -12
  11. package/dist/components/callout/index.d.ts +2 -0
  12. package/dist/components/card/index.d.ts +12 -0
  13. package/dist/components/carousel/index.d.ts +4 -0
  14. package/dist/components/close-button/index.d.ts +2 -0
  15. package/dist/components/collapse/index.d.ts +2 -0
  16. package/dist/components/date-picker/CDatePicker.d.ts +13 -0
  17. package/dist/components/date-picker/index.d.ts +2 -0
  18. package/dist/components/date-range-picker/CDateRangePicker.d.ts +93 -0
  19. package/dist/components/date-range-picker/index.d.ts +2 -0
  20. package/dist/components/datepicker/index.d.ts +2 -0
  21. package/dist/components/daterangepicker/CDateRangePicker.d.ts +26 -11
  22. package/dist/components/daterangepicker/index.d.ts +2 -0
  23. package/dist/components/dropdown/index.d.ts +8 -0
  24. package/dist/components/footer/index.d.ts +2 -0
  25. package/dist/components/form/CForm.d.ts +2 -2
  26. package/dist/components/form/CFormCheck.d.ts +2 -1
  27. package/dist/components/form/CFormControlValidation.d.ts +46 -0
  28. package/dist/components/form/CFormControlWrapper.d.ts +31 -0
  29. package/dist/components/form/CFormInput.d.ts +6 -9
  30. package/dist/components/form/CFormRange.d.ts +7 -1
  31. package/dist/components/form/CFormSelect.d.ts +3 -10
  32. package/dist/components/form/CFormTextarea.d.ts +2 -9
  33. package/dist/components/form/index.d.ts +14 -0
  34. package/dist/components/grid/index.d.ts +4 -0
  35. package/dist/components/header/index.d.ts +7 -0
  36. package/dist/components/image/index.d.ts +2 -0
  37. package/dist/components/index.d.ts +41 -0
  38. package/dist/components/link/index.d.ts +2 -0
  39. package/dist/components/list-group/index.d.ts +3 -0
  40. package/dist/components/loading-button/index.d.ts +2 -0
  41. package/dist/components/modal/CModal.d.ts +3 -0
  42. package/dist/components/modal/index.d.ts +8 -0
  43. package/dist/components/multi-select/index.d.ts +2 -0
  44. package/dist/components/nav/index.d.ts +7 -0
  45. package/dist/components/navbar/index.d.ts +6 -0
  46. package/dist/components/offcanvas/index.d.ts +5 -0
  47. package/dist/components/pagination/index.d.ts +4 -0
  48. package/dist/components/picker/CPicker.d.ts +52 -7
  49. package/dist/components/placeholder/index.d.ts +2 -0
  50. package/dist/components/popover/CPopover.d.ts +2 -2
  51. package/dist/components/popover/index.d.ts +2 -0
  52. package/dist/components/progress/index.d.ts +3 -0
  53. package/dist/components/sidebar/index.d.ts +7 -0
  54. package/dist/components/smart-table/index.d.ts +2 -0
  55. package/dist/components/spinner/index.d.ts +2 -0
  56. package/dist/components/table/index.d.ts +9 -0
  57. package/dist/components/tabs/index.d.ts +3 -0
  58. package/dist/components/time-picker/CTimePicker.d.ts +45 -0
  59. package/dist/components/time-picker/CTimePickerRollCol.d.ts +11 -0
  60. package/dist/components/time-picker/index.d.ts +2 -0
  61. package/dist/components/timepicker/CTimePicker.d.ts +9 -13
  62. package/dist/components/timepicker/index.d.ts +2 -0
  63. package/dist/components/toast/index.d.ts +6 -0
  64. package/dist/components/tooltip/CTooltip.d.ts +6 -2
  65. package/dist/components/tooltip/index.d.ts +2 -0
  66. package/dist/index.d.ts +0 -128
  67. package/dist/index.es.js +8368 -5764
  68. package/dist/index.es.js.map +1 -1
  69. package/dist/index.js +8367 -5764
  70. package/dist/index.js.map +1 -1
  71. package/dist/{components/calendar/CCalendar.utils.d.ts → utils/calendar.d.ts} +5 -2
  72. package/dist/utils/hooks/useStateWithCallback.d.ts +2 -1
  73. package/dist/utils/time.d.ts +21 -0
  74. package/package.json +14 -11
  75. package/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.tsx.snap +2 -0
  76. package/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.tsx.snap +2 -0
  77. package/src/components/accordion/index.ts +15 -0
  78. package/src/components/alert/CAlert.tsx +14 -3
  79. package/src/components/alert/index.ts +5 -0
  80. package/src/components/avatar/index.ts +3 -0
  81. package/src/components/backdrop/CBackdrop.tsx +10 -3
  82. package/src/components/backdrop/index.ts +3 -0
  83. package/src/components/badge/index.ts +3 -0
  84. package/src/components/breadcrumb/index.ts +4 -0
  85. package/src/components/button/index.ts +3 -0
  86. package/src/components/button-group/index.ts +4 -0
  87. package/src/components/calendar/CCalendar.tsx +221 -131
  88. package/src/components/calendar/__tests__/CCalendar.spec.tsx +9 -0
  89. package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +573 -0
  90. package/src/components/callout/index.ts +3 -0
  91. package/src/components/card/index.ts +25 -0
  92. package/src/components/carousel/index.ts +5 -0
  93. package/src/components/close-button/index.ts +3 -0
  94. package/src/components/collapse/CCollapse.tsx +1 -0
  95. package/src/components/collapse/index.ts +3 -0
  96. package/src/components/{datepicker → date-picker}/CDatePicker.tsx +3 -2
  97. package/src/components/date-picker/__tests__/CDatePicker.spec.tsx +9 -0
  98. package/src/components/date-picker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +617 -0
  99. package/src/components/date-picker/index.ts +3 -0
  100. package/src/components/date-range-picker/CDateRangePicker.tsx +495 -0
  101. package/src/components/date-range-picker/__tests__/CDateRangePicker.spec.tsx +9 -0
  102. package/src/components/date-range-picker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +1201 -0
  103. package/src/components/date-range-picker/index.ts +3 -0
  104. package/src/components/dropdown/CDropdownItem.tsx +1 -1
  105. package/src/components/dropdown/CDropdownMenu.tsx +14 -14
  106. package/src/components/dropdown/index.ts +17 -0
  107. package/src/components/footer/index.ts +3 -0
  108. package/src/components/form/CForm.tsx +2 -2
  109. package/src/components/form/CFormCheck.tsx +32 -7
  110. package/src/components/form/CFormControlValidation.tsx +97 -0
  111. package/src/components/form/CFormControlWrapper.tsx +85 -0
  112. package/src/components/form/CFormInput.tsx +75 -19
  113. package/src/components/form/CFormRange.tsx +18 -4
  114. package/src/components/form/CFormSelect.tsx +60 -32
  115. package/src/components/form/CFormTextarea.tsx +45 -17
  116. package/src/components/form/index.ts +29 -0
  117. package/src/components/grid/index.ts +5 -0
  118. package/src/components/header/index.ts +8 -0
  119. package/src/components/image/index.ts +3 -0
  120. package/src/components/index.ts +41 -0
  121. package/src/components/link/index.ts +3 -0
  122. package/src/components/list-group/index.ts +4 -0
  123. package/src/components/loading-button/index.ts +3 -0
  124. package/src/components/modal/CModal.tsx +3 -2
  125. package/src/components/modal/index.ts +9 -0
  126. package/src/components/multi-select/CMultiSelect.tsx +46 -38
  127. package/src/components/multi-select/index.ts +3 -0
  128. package/src/components/nav/CNavGroup.tsx +1 -0
  129. package/src/components/nav/index.ts +8 -0
  130. package/src/components/navbar/index.ts +7 -0
  131. package/src/components/offcanvas/COffcanvas.tsx +1 -0
  132. package/src/components/offcanvas/index.ts +6 -0
  133. package/src/components/pagination/index.ts +5 -0
  134. package/src/components/picker/CPicker.tsx +104 -32
  135. package/src/components/picker/__tests__/CPicker.spec.tsx +9 -0
  136. package/src/components/picker/__tests__/__snapshots__/CPicker.spec.tsx.snap +23 -0
  137. package/src/components/placeholder/index.ts +3 -0
  138. package/src/components/popover/CPopover.tsx +59 -57
  139. package/src/components/popover/index.ts +3 -0
  140. package/src/components/progress/index.ts +4 -0
  141. package/src/components/sidebar/index.ts +8 -0
  142. package/src/components/smart-table/CSmartTable.tsx +2 -2
  143. package/src/components/smart-table/index.ts +3 -0
  144. package/src/components/spinner/index.ts +3 -0
  145. package/src/components/table/index.ts +19 -0
  146. package/src/components/tabs/CTabPane.tsx +7 -3
  147. package/src/components/tabs/index.ts +4 -0
  148. package/src/components/{timepicker → time-picker}/CTimePicker.tsx +71 -98
  149. package/src/components/{timepicker → time-picker}/CTimePickerRollCol.tsx +7 -1
  150. package/src/components/time-picker/__tests__/CTimePicker.spec.tsx +9 -0
  151. package/src/components/time-picker/index.ts +3 -0
  152. package/src/components/toast/CToast.tsx +6 -1
  153. package/src/components/toast/index.ts +7 -0
  154. package/src/components/tooltip/CTooltip.tsx +63 -45
  155. package/src/components/tooltip/index.ts +3 -0
  156. package/src/index.ts +0 -258
  157. package/src/{components/calendar/CCalendar.utils.ts → utils/calendar.ts} +97 -10
  158. package/src/utils/hooks/useStateWithCallback.ts +6 -3
  159. package/src/utils/time.ts +84 -0
  160. package/dist/components/dropdown/CDropdownToggleCustom.d.ts +0 -15
  161. package/dist/components/timepicker/CTimePicker.utils.d.ts +0 -4
  162. package/src/components/daterangepicker/CDateRangePicker.tsx +0 -366
  163. package/src/components/timepicker/CTimePicker.utils.ts +0 -27
@@ -0,0 +1,3 @@
1
+ import { CDateRangePicker } from './CDateRangePicker'
2
+
3
+ export { CDateRangePicker }
@@ -21,7 +21,7 @@ export const CDropdownItem = forwardRef<HTMLButtonElement | HTMLAnchorElement, C
21
21
  const _className = classNames('dropdown-item', className)
22
22
 
23
23
  return (
24
- <CLink component={component} {...rest} className={_className} ref={ref}>
24
+ <CLink className={_className} component={component} {...rest} ref={ref}>
25
25
  {children}
26
26
  </CLink>
27
27
  )
@@ -1,5 +1,5 @@
1
- import PropTypes from 'prop-types'
2
1
  import React, { ElementType, FC, HTMLAttributes, useContext, useEffect, useRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
  import { Popper, PopperChildrenProps } from 'react-popper'
5
5
 
@@ -59,31 +59,28 @@ export const CDropdownMenu: FC<CDropdownMenuProps> = ({
59
59
  }
60
60
  }, [visible])
61
61
 
62
- const handleKeyup = (event: Event) => {
62
+ const handleKeyup = (event: KeyboardEvent) => {
63
63
  if (autoClose === false) {
64
64
  return
65
65
  }
66
- if (!dropdownMenuRef.current?.contains(event.target as HTMLElement)) {
66
+
67
+ if (event.key === 'Escape') {
67
68
  setVisible(false)
68
69
  }
69
70
  }
71
+
70
72
  const handleMouseUp = (event: Event) => {
71
73
  if (dropdownToggleRef && dropdownToggleRef.current.contains(event.target as HTMLElement)) {
72
74
  return
73
75
  }
74
- if (autoClose === true) {
75
- setVisible(false)
76
- return
77
- }
78
- if (autoClose === 'inside' && dropdownMenuRef.current?.contains(event.target as HTMLElement)) {
79
- setVisible(false)
80
- return
81
- }
76
+
82
77
  if (
83
- autoClose === 'outside' &&
84
- !dropdownMenuRef.current?.contains(event.target as HTMLElement)
78
+ autoClose === true ||
79
+ (autoClose === 'inside' && dropdownMenuRef.current?.contains(event.target as HTMLElement)) ||
80
+ (autoClose === 'outside' && !dropdownMenuRef.current?.contains(event.target as HTMLElement))
85
81
  ) {
86
- setVisible(false)
82
+ setTimeout(() => setVisible(false), 1)
83
+ return
87
84
  }
88
85
  }
89
86
 
@@ -92,12 +89,15 @@ export const CDropdownMenu: FC<CDropdownMenuProps> = ({
92
89
  if (direction === 'dropup') {
93
90
  _placement = 'top-start'
94
91
  }
92
+
95
93
  if (direction === 'dropend') {
96
94
  _placement = 'right-start'
97
95
  }
96
+
98
97
  if (direction === 'dropstart') {
99
98
  _placement = 'left-start'
100
99
  }
100
+
101
101
  if (alignment === 'end') {
102
102
  _placement = 'bottom-end'
103
103
  }
@@ -0,0 +1,17 @@
1
+ import { CDropdown } from './CDropdown'
2
+ import { CDropdownDivider } from './CDropdownDivider'
3
+ import { CDropdownHeader } from './CDropdownHeader'
4
+ import { CDropdownItem } from './CDropdownItem'
5
+ import { CDropdownItemPlain } from './CDropdownItemPlain'
6
+ import { CDropdownMenu } from './CDropdownMenu'
7
+ import { CDropdownToggle } from './CDropdownToggle'
8
+
9
+ export {
10
+ CDropdown,
11
+ CDropdownDivider,
12
+ CDropdownHeader,
13
+ CDropdownItem,
14
+ CDropdownItemPlain,
15
+ CDropdownMenu,
16
+ CDropdownToggle,
17
+ }
@@ -0,0 +1,3 @@
1
+ import { CFooter } from './CFooter'
2
+
3
+ export { CFooter }
@@ -1,8 +1,8 @@
1
- import React, { forwardRef, HTMLAttributes } from 'react'
1
+ import React, { forwardRef, FormHTMLAttributes } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
- export interface CFormProps extends HTMLAttributes<HTMLFormElement> {
5
+ export interface CFormProps extends FormHTMLAttributes<HTMLFormElement> {
6
6
  /**
7
7
  * A string of all className you want applied to the component.
8
8
  */
@@ -5,6 +5,7 @@ import classNames from 'classnames'
5
5
  import { useForkedRef } from '../../utils/hooks'
6
6
  import { Colors, Shapes } from '../Types'
7
7
 
8
+ import { CFormControlValidation, CFormControlValidationProps } from './CFormControlValidation'
8
9
  import { CFormLabel } from './CFormLabel'
9
10
 
10
11
  export type ButtonObject = {
@@ -30,7 +31,9 @@ export type ButtonObject = {
30
31
  variant?: 'outline' | 'ghost'
31
32
  }
32
33
 
33
- export interface CFormCheckProps extends InputHTMLAttributes<HTMLInputElement> {
34
+ export interface CFormCheckProps
35
+ extends CFormControlValidationProps,
36
+ InputHTMLAttributes<HTMLInputElement> {
34
37
  /**
35
38
  * Create button-like checkboxes and radio buttons.
36
39
  */
@@ -78,6 +81,11 @@ export const CFormCheck = forwardRef<HTMLInputElement, CFormCheckProps>(
78
81
  {
79
82
  className,
80
83
  button,
84
+ feedback,
85
+ feedbackInvalid,
86
+ feedbackValid,
87
+ floatingLabel,
88
+ tooltipFeedback,
81
89
  hitArea,
82
90
  id,
83
91
  indeterminate,
@@ -131,6 +139,19 @@ export const CFormCheck = forwardRef<HTMLInputElement, CFormCheckProps>(
131
139
  return <input type={type} className={inputClassName} id={id} {...rest} ref={forkedRef} />
132
140
  }
133
141
 
142
+ const formValidation = () => (
143
+ <CFormControlValidation
144
+ describedby={rest['aria-describedby']}
145
+ feedback={feedback}
146
+ feedbackInvalid={feedbackInvalid}
147
+ feedbackValid={feedbackValid}
148
+ floatingLabel={floatingLabel}
149
+ invalid={invalid}
150
+ tooltipFeedback={tooltipFeedback}
151
+ valid={valid}
152
+ />
153
+ )
154
+
134
155
  const formLabel = () => {
135
156
  return (
136
157
  <CFormLabel customClassName={labelClassName} {...(id && { htmlFor: id })}>
@@ -143,17 +164,22 @@ export const CFormCheck = forwardRef<HTMLInputElement, CFormCheckProps>(
143
164
  <>
144
165
  {formControl()}
145
166
  {label && formLabel()}
167
+ {formValidation()}
146
168
  </>
147
169
  ) : label ? (
148
170
  hitArea ? (
149
- <CFormLabel customClassName={className} {...(id && { htmlFor: id })}>
150
- {formControl()}
151
- {label}
152
- </CFormLabel>
171
+ <>
172
+ <CFormLabel customClassName={className} {...(id && { htmlFor: id })}>
173
+ {formControl()}
174
+ {label}
175
+ </CFormLabel>
176
+ {formValidation()}
177
+ </>
153
178
  ) : (
154
179
  <div className={_className}>
155
180
  {formControl()}
156
181
  {formLabel()}
182
+ {formValidation()}
157
183
  </div>
158
184
  )
159
185
  ) : (
@@ -169,10 +195,9 @@ CFormCheck.propTypes = {
169
195
  id: PropTypes.string,
170
196
  indeterminate: PropTypes.bool,
171
197
  inline: PropTypes.bool,
172
- invalid: PropTypes.bool,
173
198
  label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
174
199
  type: PropTypes.oneOf(['checkbox', 'radio']),
175
- valid: PropTypes.bool,
200
+ ...CFormControlValidation.propTypes,
176
201
  }
177
202
 
178
203
  CFormCheck.displayName = 'CFormCheck'
@@ -0,0 +1,97 @@
1
+ import React, { FC, ReactNode } from 'react'
2
+
3
+ import PropTypes from 'prop-types'
4
+
5
+ import { CFormFeedback } from './CFormFeedback'
6
+
7
+ export interface CFormControlValidationProps {
8
+ /**
9
+ * @ignore
10
+ */
11
+ describedby?: string
12
+ /**
13
+ * Provide valuable, actionable feedback.
14
+ *
15
+ * @since 4.2.0
16
+ */
17
+ feedback?: ReactNode | string
18
+ /**
19
+ * Provide valuable, actionable feedback.
20
+ *
21
+ * @since 4.2.0
22
+ */
23
+ feedbackInvalid?: ReactNode | string
24
+ /**
25
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
26
+ *
27
+ * @since 4.2.0
28
+ */
29
+ feedbackValid?: ReactNode | string
30
+ /**
31
+ * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
32
+ *
33
+ * @since 4.2.0
34
+ */
35
+ floatingLabel?: ReactNode | string
36
+ /**
37
+ * Set component validation state to invalid.
38
+ */
39
+ invalid?: boolean
40
+ /**
41
+ * Display validation feedback in a styled tooltip.
42
+ *
43
+ * @since 4.2.0
44
+ */
45
+ tooltipFeedback?: boolean
46
+ /**
47
+ * Set component validation state to valid.
48
+ */
49
+ valid?: boolean
50
+ }
51
+
52
+ export const CFormControlValidation: FC<CFormControlValidationProps> = ({
53
+ describedby,
54
+ feedback,
55
+ feedbackInvalid,
56
+ feedbackValid,
57
+ invalid,
58
+ tooltipFeedback,
59
+ valid,
60
+ }) => {
61
+ return (
62
+ <>
63
+ {feedback && (valid || invalid) && (
64
+ <CFormFeedback
65
+ {...(invalid && { id: describedby })}
66
+ invalid={invalid}
67
+ tooltip={tooltipFeedback}
68
+ valid={valid}
69
+ >
70
+ {feedback}
71
+ </CFormFeedback>
72
+ )}
73
+ {feedbackInvalid && (
74
+ <CFormFeedback id={describedby} invalid tooltip={tooltipFeedback}>
75
+ {feedbackInvalid}
76
+ </CFormFeedback>
77
+ )}
78
+ {feedbackValid && (
79
+ <CFormFeedback valid tooltip={tooltipFeedback}>
80
+ {feedbackValid}
81
+ </CFormFeedback>
82
+ )}
83
+ </>
84
+ )
85
+ }
86
+
87
+ CFormControlValidation.propTypes = {
88
+ describedby: PropTypes.string,
89
+ feedback: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
90
+ feedbackValid: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
91
+ feedbackInvalid: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
92
+ invalid: PropTypes.bool,
93
+ tooltipFeedback: PropTypes.bool,
94
+ valid: PropTypes.bool,
95
+ }
96
+
97
+ CFormControlValidation.displayName = 'CFormControlValidation'
@@ -0,0 +1,85 @@
1
+ import React, { FC, ReactNode } from 'react'
2
+
3
+ import PropTypes from 'prop-types'
4
+
5
+ import { CFormControlValidation, CFormControlValidationProps } from './CFormControlValidation'
6
+ import { CFormFloating } from './CFormFloating'
7
+ import { CFormLabel } from './CFormLabel'
8
+ import { CFormText } from './CFormText'
9
+
10
+ export interface CFormControlWrapperProps extends CFormControlValidationProps {
11
+ /**
12
+ * @ignore
13
+ */
14
+ children?: ReactNode
15
+ /**
16
+ * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
17
+ *
18
+ * @since 4.2.0
19
+ */
20
+ floatingLabel?: ReactNode | string
21
+ /**
22
+ * @ignore
23
+ */
24
+ id?: string
25
+ /**
26
+ * Add a caption for a component.
27
+ *
28
+ * @since 4.2.0
29
+ */
30
+ label?: ReactNode | string
31
+ /**
32
+ * Add helper text to the component.
33
+ *
34
+ * @since 4.2.0
35
+ */
36
+ text?: ReactNode | string
37
+ }
38
+
39
+ export const CFormControlWrapper: FC<CFormControlWrapperProps> = ({
40
+ children,
41
+ describedby,
42
+ feedback,
43
+ feedbackInvalid,
44
+ feedbackValid,
45
+ floatingLabel,
46
+ id,
47
+ invalid,
48
+ label,
49
+ text,
50
+ tooltipFeedback,
51
+ valid,
52
+ }) => {
53
+ return floatingLabel ? (
54
+ <CFormFloating>
55
+ {children}
56
+ <CFormLabel htmlFor={id}>{label || floatingLabel}</CFormLabel>
57
+ </CFormFloating>
58
+ ) : (
59
+ <>
60
+ {label && <CFormLabel htmlFor={id}>{label}</CFormLabel>}
61
+ {children}
62
+ {text && <CFormText id={describedby}>{text}</CFormText>}
63
+ <CFormControlValidation
64
+ describedby={describedby}
65
+ feedback={feedback}
66
+ feedbackInvalid={feedbackInvalid}
67
+ feedbackValid={feedbackValid}
68
+ floatingLabel={floatingLabel}
69
+ invalid={invalid}
70
+ tooltipFeedback={tooltipFeedback}
71
+ valid={valid}
72
+ />
73
+ </>
74
+ )
75
+ }
76
+
77
+ CFormControlWrapper.propTypes = {
78
+ children: PropTypes.node,
79
+ floatingLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
80
+ label: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
81
+ text: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
82
+ ...CFormControlValidation.propTypes,
83
+ }
84
+
85
+ CFormControlWrapper.displayName = 'CFormControlWrapper'
@@ -1,21 +1,26 @@
1
- import React, { ChangeEventHandler, forwardRef, InputHTMLAttributes } from 'react'
2
- import PropTypes from 'prop-types'
1
+ import React, { ChangeEventHandler, forwardRef, InputHTMLAttributes, useState } from 'react'
2
+
3
3
  import classNames from 'classnames'
4
- // import { CFormLabel } from './CFormLabel'
4
+ import PropTypes from 'prop-types'
5
+
6
+ import { CFormControlWrapper, CFormControlWrapperProps } from './CFormControlWrapper'
7
+ import { useEffect } from 'react'
5
8
 
6
- export interface CFormInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
9
+ export interface CFormInputProps
10
+ extends CFormControlWrapperProps,
11
+ Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
7
12
  /**
8
13
  * A string of all className you want applied to the component.
9
14
  */
10
15
  className?: string
11
16
  /**
12
- * Toggle the disabled state for the component.
17
+ * Delay onChange event while typing. If set to true onChange event will be delayed 500ms, you can also provide the number of milliseconds you want to delay the onChange event.
13
18
  */
14
- disabled?: boolean
19
+ delay?: boolean | number
15
20
  /**
16
- * Set component validation state to invalid.
21
+ * Toggle the disabled state for the component.
17
22
  */
18
- invalid?: boolean
23
+ disabled?: boolean
19
24
  /**
20
25
  * Method called immediately after the `value` prop changes.
21
26
  */
@@ -36,10 +41,6 @@ export interface CFormInputProps extends Omit<InputHTMLAttributes<HTMLInputEleme
36
41
  * Specifies the type of component.
37
42
  */
38
43
  type?: 'color' | 'file' | 'text' | string
39
- /**
40
- * Set component validation state to valid.
41
- */
42
- valid?: boolean
43
44
  /**
44
45
  * The `value` attribute of component.
45
46
  *
@@ -49,7 +50,40 @@ export interface CFormInputProps extends Omit<InputHTMLAttributes<HTMLInputEleme
49
50
  }
50
51
 
51
52
  export const CFormInput = forwardRef<HTMLInputElement, CFormInputProps>(
52
- ({ children, className, invalid, plainText, size, type = 'text', valid, ...rest }, ref) => {
53
+ (
54
+ {
55
+ children,
56
+ className,
57
+ delay = false,
58
+ feedback,
59
+ feedbackInvalid,
60
+ feedbackValid,
61
+ floatingLabel,
62
+ id,
63
+ invalid,
64
+ label,
65
+ onChange,
66
+ plainText,
67
+ size,
68
+ text,
69
+ tooltipFeedback,
70
+ type = 'text',
71
+ valid,
72
+ ...rest
73
+ },
74
+ ref,
75
+ ) => {
76
+ const [value, setValue] = useState<React.ChangeEvent<HTMLInputElement>>()
77
+
78
+ useEffect(() => {
79
+ const timeOutId = setTimeout(
80
+ () => value && onChange && onChange(value),
81
+ typeof delay === 'number' ? delay : 500,
82
+ )
83
+
84
+ return () => clearTimeout(timeOutId)
85
+ }, [value])
86
+
53
87
  const _className = classNames(
54
88
  plainText ? 'form-control-plaintext' : 'form-control',
55
89
  {
@@ -60,22 +94,44 @@ export const CFormInput = forwardRef<HTMLInputElement, CFormInputProps>(
60
94
  },
61
95
  className,
62
96
  )
97
+
63
98
  return (
64
- <input type={type} className={_className} {...rest} ref={ref}>
65
- {children}
66
- </input>
99
+ <CFormControlWrapper
100
+ describedby={rest['aria-describedby']}
101
+ feedback={feedback}
102
+ feedbackInvalid={feedbackInvalid}
103
+ feedbackValid={feedbackValid}
104
+ floatingLabel={floatingLabel}
105
+ id={id}
106
+ invalid={invalid}
107
+ label={label}
108
+ text={text}
109
+ tooltipFeedback={tooltipFeedback}
110
+ valid={valid}
111
+ >
112
+ <input
113
+ className={_className}
114
+ id={id}
115
+ type={type}
116
+ onChange={(event) => (delay ? setValue(event) : onChange && onChange(event))}
117
+ {...rest}
118
+ ref={ref}
119
+ >
120
+ {children}
121
+ </input>
122
+ </CFormControlWrapper>
67
123
  )
68
124
  },
69
125
  )
70
126
 
71
127
  CFormInput.propTypes = {
72
- children: PropTypes.node,
73
128
  className: PropTypes.string,
74
- invalid: PropTypes.bool,
129
+ id: PropTypes.string,
130
+ delay: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
75
131
  plainText: PropTypes.bool,
76
132
  size: PropTypes.oneOf(['sm', 'lg']),
77
133
  type: PropTypes.oneOfType([PropTypes.oneOf(['color', 'file', 'text']), PropTypes.string]),
78
- valid: PropTypes.bool,
134
+ ...CFormControlWrapper.propTypes,
79
135
  }
80
136
 
81
137
  CFormInput.displayName = 'CFormInput'
@@ -1,7 +1,9 @@
1
- import React, { ChangeEventHandler, forwardRef, InputHTMLAttributes } from 'react'
2
- import PropTypes from 'prop-types'
1
+ import React, { ChangeEventHandler, forwardRef, InputHTMLAttributes, ReactNode } from 'react'
2
+
3
3
  import classNames from 'classnames'
4
+ import PropTypes from 'prop-types'
4
5
 
6
+ import { CFormLabel } from './CFormLabel'
5
7
  export interface CFormRangeProps extends InputHTMLAttributes<HTMLInputElement> {
6
8
  /**
7
9
  * A string of all className you want applied to the component.
@@ -11,6 +13,12 @@ export interface CFormRangeProps extends InputHTMLAttributes<HTMLInputElement> {
11
13
  * Toggle the disabled state for the component.
12
14
  */
13
15
  disabled?: boolean
16
+ /**
17
+ * Add a caption for a component.
18
+ *
19
+ * @since 4.2.0
20
+ */
21
+ label?: ReactNode | string
14
22
  /**
15
23
  * Specifies the maximum value for the component.
16
24
  */
@@ -40,14 +48,20 @@ export interface CFormRangeProps extends InputHTMLAttributes<HTMLInputElement> {
40
48
  }
41
49
 
42
50
  export const CFormRange = forwardRef<HTMLInputElement, CFormRangeProps>(
43
- ({ className, ...rest }, ref) => {
51
+ ({ className, label, ...rest }, ref) => {
44
52
  const _className = classNames('form-range', className)
45
- return <input type="range" className={_className} {...rest} ref={ref} />
53
+ return (
54
+ <>
55
+ {label && <CFormLabel htmlFor={rest.id}>{label}</CFormLabel>}
56
+ <input type="range" className={_className} {...rest} ref={ref} />
57
+ </>
58
+ )
46
59
  },
47
60
  )
48
61
 
49
62
  CFormRange.propTypes = {
50
63
  className: PropTypes.string,
64
+ label: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
51
65
  }
52
66
 
53
67
  CFormRange.displayName = 'CFormRange'