@coreui/react 4.4.1 → 4.5.1

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.
@@ -0,0 +1,2 @@
1
+ import isVisible from './isVisible';
2
+ export { isVisible };
@@ -0,0 +1,2 @@
1
+ declare const isVisible: (element: HTMLElement) => boolean;
2
+ export default isVisible;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreui/react",
3
- "version": "4.4.1",
3
+ "version": "4.5.1",
4
4
  "description": "UI Components Library for React.js",
5
5
  "keywords": [
6
6
  "react",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@popperjs/core": "^2.11.5",
39
- "@rollup/plugin-commonjs": "^23.0.4",
39
+ "@rollup/plugin-commonjs": "^23.0.7",
40
40
  "@rollup/plugin-node-resolve": "^15.0.1",
41
41
  "@rollup/plugin-typescript": "^10.0.1",
42
42
  "@testing-library/jest-dom": "^5.16.5",
@@ -50,7 +50,7 @@
50
50
  "react-dom": "^18.2.0",
51
51
  "react-popper": "^2.2.5",
52
52
  "react-transition-group": "^4.4.5",
53
- "rollup": "^3.7.2",
53
+ "rollup": "^3.7.5",
54
54
  "tslib": "^2.4.1",
55
55
  "typescript": "^4.9.4"
56
56
  },
@@ -3,6 +3,7 @@ import React, {
3
3
  createContext,
4
4
  forwardRef,
5
5
  HTMLAttributes,
6
+ TouchEvent,
6
7
  useState,
7
8
  useEffect,
8
9
  useRef,
@@ -10,18 +11,9 @@ import React, {
10
11
  import PropTypes from 'prop-types'
11
12
  import classNames from 'classnames'
12
13
 
14
+ import { isVisible } from '../../utils'
13
15
  import { useForkedRef } from '../../utils/hooks'
14
16
 
15
- const isVisible = (element: HTMLDivElement) => {
16
- const rect = element.getBoundingClientRect()
17
- return (
18
- rect.top >= 0 &&
19
- rect.left >= 0 &&
20
- rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
21
- rect.right <= (window.innerWidth || document.documentElement.clientWidth)
22
- )
23
- }
24
-
25
17
  export interface CCarouselProps extends HTMLAttributes<HTMLDivElement> {
26
18
  /**
27
19
  * index of the active item.
@@ -59,6 +51,12 @@ export interface CCarouselProps extends HTMLAttributes<HTMLDivElement> {
59
51
  * If set to 'hover', pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on mouseleave. If set to false, hovering over the carousel won't pause it.
60
52
  */
61
53
  pause?: boolean | 'hover'
54
+ /**
55
+ * Set whether the carousel should support left/right swipe interactions on touchscreen devices.
56
+ *
57
+ * @since 4.5.0
58
+ */
59
+ touch?: boolean
62
60
  /**
63
61
  * Set type of the transition.
64
62
  */
@@ -93,6 +91,7 @@ export const CCarousel = forwardRef<HTMLDivElement, CCarouselProps>(
93
91
  onSlid,
94
92
  onSlide,
95
93
  pause = 'hover',
94
+ touch = true,
96
95
  transition,
97
96
  wrap = true,
98
97
  ...rest
@@ -108,6 +107,7 @@ export const CCarousel = forwardRef<HTMLDivElement, CCarouselProps>(
108
107
  const [customInterval, setCustomInterval] = useState<boolean | number>()
109
108
  const [direction, setDirection] = useState<string>('next')
110
109
  const [itemsNumber, setItemsNumber] = useState<number>(0)
110
+ const [touchPosition, setTouchPosition] = useState<number | null>(null)
111
111
  const [visible, setVisible] = useState<boolean>()
112
112
 
113
113
  useEffect(() => {
@@ -202,11 +202,38 @@ export const CCarousel = forwardRef<HTMLDivElement, CCarouselProps>(
202
202
  }
203
203
  }
204
204
 
205
+ const handleTouchMove = (e: TouchEvent) => {
206
+ const touchDown = touchPosition
207
+
208
+ if (touchDown === null) {
209
+ return
210
+ }
211
+
212
+ const currentTouch = e.touches[0].clientX
213
+ const diff = touchDown - currentTouch
214
+
215
+ if (diff > 5) {
216
+ handleControlClick('next')
217
+ }
218
+
219
+ if (diff < -5) {
220
+ handleControlClick('prev')
221
+ }
222
+
223
+ setTouchPosition(null)
224
+ }
225
+
226
+ const handleTouchStart = (e: TouchEvent) => {
227
+ const touchDown = e.touches[0].clientX
228
+ setTouchPosition(touchDown)
229
+ }
230
+
205
231
  return (
206
232
  <div
207
233
  className={_className}
208
234
  onMouseEnter={_pause}
209
235
  onMouseLeave={cycle}
236
+ {...(touch && { onTouchStart: handleTouchStart, onTouchMove: handleTouchMove })}
210
237
  {...rest}
211
238
  ref={forkedRef}
212
239
  >
@@ -271,6 +298,7 @@ CCarousel.propTypes = {
271
298
  onSlid: PropTypes.func,
272
299
  onSlide: PropTypes.func,
273
300
  pause: PropTypes.oneOf([false, 'hover']),
301
+ touch: PropTypes.bool,
274
302
  transition: PropTypes.oneOf(['slide', 'crossfade']),
275
303
  wrap: PropTypes.bool,
276
304
  }
@@ -12,6 +12,12 @@ export interface CFormControlWrapperProps extends CFormControlValidationProps {
12
12
  * @ignore
13
13
  */
14
14
  children?: ReactNode
15
+ /**
16
+ * A string of all className you want applied to the floating label wrapper.
17
+ *
18
+ * @since 4.5.0
19
+ */
20
+ floatingClassName?: string
15
21
  /**
16
22
  * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
17
23
  *
@@ -42,6 +48,7 @@ export const CFormControlWrapper: FC<CFormControlWrapperProps> = ({
42
48
  feedback,
43
49
  feedbackInvalid,
44
50
  feedbackValid,
51
+ floatingClassName,
45
52
  floatingLabel,
46
53
  id,
47
54
  invalid,
@@ -51,9 +58,20 @@ export const CFormControlWrapper: FC<CFormControlWrapperProps> = ({
51
58
  valid,
52
59
  }) => {
53
60
  return floatingLabel ? (
54
- <CFormFloating>
61
+ <CFormFloating className={floatingClassName}>
55
62
  {children}
56
63
  <CFormLabel htmlFor={id}>{label || floatingLabel}</CFormLabel>
64
+ {text && <CFormText id={describedby}>{text}</CFormText>}
65
+ <CFormControlValidation
66
+ describedby={describedby}
67
+ feedback={feedback}
68
+ feedbackInvalid={feedbackInvalid}
69
+ feedbackValid={feedbackValid}
70
+ floatingLabel={floatingLabel}
71
+ invalid={invalid}
72
+ tooltipFeedback={tooltipFeedback}
73
+ valid={valid}
74
+ />
57
75
  </CFormFloating>
58
76
  ) : (
59
77
  <>
@@ -76,6 +94,7 @@ export const CFormControlWrapper: FC<CFormControlWrapperProps> = ({
76
94
 
77
95
  CFormControlWrapper.propTypes = {
78
96
  children: PropTypes.node,
97
+ floatingClassName: PropTypes.string,
79
98
  floatingLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
80
99
  label: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
81
100
  text: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
@@ -58,6 +58,7 @@ export const CFormInput = forwardRef<HTMLInputElement, CFormInputProps>(
58
58
  feedback,
59
59
  feedbackInvalid,
60
60
  feedbackValid,
61
+ floatingClassName,
61
62
  floatingLabel,
62
63
  id,
63
64
  invalid,
@@ -101,6 +102,7 @@ export const CFormInput = forwardRef<HTMLInputElement, CFormInputProps>(
101
102
  feedback={feedback}
102
103
  feedbackInvalid={feedbackInvalid}
103
104
  feedbackValid={feedbackValid}
105
+ floatingClassName={floatingClassName}
104
106
  floatingLabel={floatingLabel}
105
107
  id={id}
106
108
  invalid={invalid}
@@ -52,6 +52,7 @@ export const CFormSelect = forwardRef<HTMLSelectElement, CFormSelectProps>(
52
52
  feedback,
53
53
  feedbackInvalid,
54
54
  feedbackValid,
55
+ floatingClassName,
55
56
  floatingLabel,
56
57
  htmlSize,
57
58
  id,
@@ -81,6 +82,7 @@ export const CFormSelect = forwardRef<HTMLSelectElement, CFormSelectProps>(
81
82
  feedback={feedback}
82
83
  feedbackInvalid={feedbackInvalid}
83
84
  feedbackValid={feedbackValid}
85
+ floatingClassName={floatingClassName}
84
86
  floatingLabel={floatingLabel}
85
87
  id={id}
86
88
  invalid={invalid}
@@ -44,6 +44,7 @@ export const CFormTextarea = forwardRef<HTMLTextAreaElement, CFormTextareaProps>
44
44
  feedback,
45
45
  feedbackInvalid,
46
46
  feedbackValid,
47
+ floatingClassName,
47
48
  floatingLabel,
48
49
  id,
49
50
  invalid,
@@ -70,6 +71,7 @@ export const CFormTextarea = forwardRef<HTMLTextAreaElement, CFormTextareaProps>
70
71
  feedback={feedback}
71
72
  feedbackInvalid={feedbackInvalid}
72
73
  feedbackValid={feedbackValid}
74
+ floatingClassName={floatingClassName}
73
75
  floatingLabel={floatingLabel}
74
76
  id={id}
75
77
  invalid={invalid}
@@ -108,6 +108,7 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
108
108
  transition = true,
109
109
  unmountOnClose = true,
110
110
  visible,
111
+ ...rest
111
112
  },
112
113
  ref,
113
114
  ) => {
@@ -233,7 +234,9 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
233
234
  scrollable={scrollable}
234
235
  size={size}
235
236
  >
236
- <CModalContent ref={modalContentRef}>{children}</CModalContent>
237
+ <CModalContent {...rest} ref={modalContentRef}>
238
+ {children}
239
+ </CModalContent>
237
240
  </CModalDialog>
238
241
  </div>
239
242
  </CModalContext.Provider>
@@ -1,17 +1,17 @@
1
- import React, { FC, ReactNode, useRef, useState } from 'react'
1
+ import React, { FC, HTMLAttributes, ReactNode, useRef, useEffect, useState } from 'react'
2
2
  import { createPortal } from 'react-dom'
3
-
4
- import classNames from 'classnames'
5
3
  import PropTypes from 'prop-types'
4
+ import classNames from 'classnames'
6
5
  import { usePopper } from 'react-popper'
7
6
  import { Transition } from 'react-transition-group'
8
7
 
9
8
  import { Triggers, triggerPropType } from '../Types'
10
- import { useEffect } from 'react'
11
9
 
12
- export interface CPopoverProps {
13
- // TODO: find solution to not use any
14
- children: any
10
+ export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
11
+ /**
12
+ * A string of all className you want applied to the component.
13
+ */
14
+ className?: string
15
15
  /**
16
16
  * Content node for your component.
17
17
  */
@@ -50,6 +50,7 @@ export interface CPopoverProps {
50
50
 
51
51
  export const CPopover: FC<CPopoverProps> = ({
52
52
  children,
53
+ className,
53
54
  content,
54
55
  offset = [0, 8],
55
56
  onHide,
@@ -95,7 +96,7 @@ export const CPopover: FC<CPopoverProps> = ({
95
96
 
96
97
  return (
97
98
  <>
98
- {React.cloneElement(children, {
99
+ {React.cloneElement(children as React.ReactElement<any>, {
99
100
  ref: setReferenceElement,
100
101
  ...((trigger === 'click' || trigger.includes('click')) && {
101
102
  onClick: () => setVisible(!_visible),
@@ -131,6 +132,7 @@ export const CPopover: FC<CPopoverProps> = ({
131
132
  `popover bs-popover-${
132
133
  placement === 'left' ? 'start' : placement === 'right' ? 'end' : placement
133
134
  }`,
135
+ className,
134
136
  transitionClass,
135
137
  )}
136
138
  ref={setPopperElement}
@@ -153,7 +155,8 @@ export const CPopover: FC<CPopoverProps> = ({
153
155
  }
154
156
 
155
157
  CPopover.propTypes = {
156
- children: PropTypes.any,
158
+ children: PropTypes.node,
159
+ className: PropTypes.string,
157
160
  content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
158
161
  offset: PropTypes.any, // TODO: find good proptype
159
162
  onHide: PropTypes.func,
@@ -3,6 +3,7 @@ import { createPortal } from 'react-dom'
3
3
  import PropTypes from 'prop-types'
4
4
  import classNames from 'classnames'
5
5
 
6
+ import { isVisible } from '../../utils'
6
7
  import { useForkedRef } from '../../utils/hooks'
7
8
  import { CBackdrop } from '../backdrop/CBackdrop'
8
9
 
@@ -52,16 +53,6 @@ export interface CSidebarProps extends HTMLAttributes<HTMLDivElement> {
52
53
  const isOnMobile = (element: HTMLDivElement) =>
53
54
  Boolean(getComputedStyle(element).getPropertyValue('--cui-is-mobile'))
54
55
 
55
- const isVisible = (element: HTMLDivElement) => {
56
- const rect = element.getBoundingClientRect()
57
- return (
58
- rect.top >= 0 &&
59
- rect.left >= 0 &&
60
- rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
61
- rect.right <= (window.innerWidth || document.documentElement.clientWidth)
62
- )
63
- }
64
-
65
56
  export const CSidebar = forwardRef<HTMLDivElement, CSidebarProps>(
66
57
  (
67
58
  {
@@ -1,6 +1,5 @@
1
- import React, { FC, ReactNode, useRef, useState } from 'react'
1
+ import React, { FC, HTMLAttributes, ReactNode, useEffect, useRef, useState } from 'react'
2
2
  import { createPortal } from 'react-dom'
3
-
4
3
  import classNames from 'classnames'
5
4
  import PropTypes from 'prop-types'
6
5
  import { usePopper } from 'react-popper'
@@ -8,9 +7,11 @@ import { Transition } from 'react-transition-group'
8
7
 
9
8
  import { Triggers, triggerPropType } from '../Types'
10
9
 
11
- export interface CTooltipProps {
12
- // TODO: find solution to not use any
13
- children: any
10
+ export interface CTooltipProps extends HTMLAttributes<HTMLDivElement> {
11
+ /**
12
+ * A string of all className you want applied to the component.
13
+ */
14
+ className?: string
14
15
  /**
15
16
  * Content node for your component.
16
17
  */
@@ -45,6 +46,7 @@ export interface CTooltipProps {
45
46
 
46
47
  export const CTooltip: FC<CTooltipProps> = ({
47
48
  children,
49
+ className,
48
50
  content,
49
51
  offset = [0, 0],
50
52
  onHide,
@@ -73,6 +75,10 @@ export const CTooltip: FC<CTooltipProps> = ({
73
75
  placement: placement,
74
76
  })
75
77
 
78
+ useEffect(() => {
79
+ setVisible(visible)
80
+ }, [visible])
81
+
76
82
  const getTransitionClass = (state: string) => {
77
83
  return state === 'entering'
78
84
  ? 'fade'
@@ -85,7 +91,7 @@ export const CTooltip: FC<CTooltipProps> = ({
85
91
 
86
92
  return (
87
93
  <>
88
- {React.cloneElement(children, {
94
+ {React.cloneElement(children as React.ReactElement<any>, {
89
95
  ref: setReferenceElement,
90
96
  ...((trigger === 'click' || trigger.includes('click')) && {
91
97
  onClick: () => setVisible(!_visible),
@@ -121,6 +127,7 @@ export const CTooltip: FC<CTooltipProps> = ({
121
127
  `tooltip bs-tooltip-${
122
128
  placement === 'left' ? 'start' : placement === 'right' ? 'end' : placement
123
129
  }`,
130
+ className,
124
131
  transitionClass,
125
132
  )}
126
133
  ref={setPopperElement}
@@ -142,7 +149,7 @@ export const CTooltip: FC<CTooltipProps> = ({
142
149
  }
143
150
 
144
151
  CTooltip.propTypes = {
145
- children: PropTypes.any,
152
+ children: PropTypes.node,
146
153
  content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
147
154
  offset: PropTypes.any, // TODO: find good proptype
148
155
  onHide: PropTypes.func,
@@ -0,0 +1,3 @@
1
+ import isVisible from './isVisible'
2
+
3
+ export { isVisible }
@@ -0,0 +1,11 @@
1
+ const isVisible = (element: HTMLElement) => {
2
+ const rect = element.getBoundingClientRect()
3
+ return (
4
+ rect.top >= 0 &&
5
+ rect.left >= 0 &&
6
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
7
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth)
8
+ )
9
+ }
10
+
11
+ export default isVisible