@coreui/react 4.7.0 → 4.9.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreui/react",
3
- "version": "4.7.0",
3
+ "version": "4.9.0-alpha.0",
4
4
  "description": "UI Components Library for React.js",
5
5
  "keywords": [
6
6
  "react",
@@ -37,15 +37,15 @@
37
37
  "test:update": "jest --coverage --updateSnapshot"
38
38
  },
39
39
  "devDependencies": {
40
- "@popperjs/core": "^2.11.6",
41
- "@rollup/plugin-commonjs": "^24.0.1",
42
- "@rollup/plugin-node-resolve": "^15.0.1",
43
- "@rollup/plugin-typescript": "^11.0.0",
40
+ "@popperjs/core": "^2.11.7",
41
+ "@rollup/plugin-commonjs": "^24.1.0",
42
+ "@rollup/plugin-node-resolve": "^15.0.2",
43
+ "@rollup/plugin-typescript": "^11.1.0",
44
44
  "@testing-library/jest-dom": "^5.16.5",
45
45
  "@testing-library/react": "^14.0.0",
46
- "@types/react": "18.0.28",
47
- "@types/react-dom": "^18.0.11",
48
- "@types/react-transition-group": "^4.4.5",
46
+ "@types/react": "18.2.6",
47
+ "@types/react-dom": "^18.2.4",
48
+ "@types/react-transition-group": "^4.4.6",
49
49
  "classnames": "^2.3.2",
50
50
  "jest": "^29.5.0",
51
51
  "jest-environment-jsdom": "^29.5.0",
@@ -54,12 +54,13 @@
54
54
  "react-dom": "^18.2.0",
55
55
  "react-popper": "^2.3.0",
56
56
  "react-transition-group": "^4.4.5",
57
- "rollup": "^3.19.1",
57
+ "rollup": "^3.21.6",
58
58
  "tslib": "^2.5.0",
59
- "ts-jest": "^29.0.5",
59
+ "ts-jest": "^29.1.0",
60
60
  "typescript": "^4.9.5"
61
61
  },
62
62
  "peerDependencies": {
63
+ "@coreui/coreui": "4.3.0-alpha.0",
63
64
  "react": ">=17",
64
65
  "react-dom": ">=17"
65
66
  }
@@ -1,7 +1,6 @@
1
1
  import { CAccordion } from './CAccordion'
2
2
  import { CAccordionBody } from './CAccordionBody'
3
3
  import { CAccordionButton } from './CAccordionButton'
4
- import { CAccordionCollapse } from './CAccordionCollapse'
5
4
  import { CAccordionHeader } from './CAccordionHeader'
6
5
  import { CAccordionItem } from './CAccordionItem'
7
6
 
@@ -9,7 +8,6 @@ export {
9
8
  CAccordion,
10
9
  CAccordionBody,
11
10
  CAccordionButton,
12
- CAccordionCollapse,
13
11
  CAccordionHeader,
14
12
  CAccordionItem,
15
13
  }
@@ -3,6 +3,7 @@ import React, {
3
3
  ElementType,
4
4
  forwardRef,
5
5
  HTMLAttributes,
6
+ ReactNode,
6
7
  RefObject,
7
8
  useEffect,
8
9
  useRef,
@@ -77,6 +78,12 @@ export interface CDropdownProps extends HTMLAttributes<HTMLDivElement | HTMLLIEl
77
78
  * If you want to disable dynamic positioning set this property to `true`.
78
79
  */
79
80
  popper?: boolean
81
+ /**
82
+ * Generates dropdown menu using createPortal.
83
+ *
84
+ * @since 4.8.0
85
+ */
86
+ portal?: boolean
80
87
  /**
81
88
  * Set the dropdown variant to an btn-group, dropdown, input-group, and nav-item.
82
89
  */
@@ -87,10 +94,15 @@ export interface CDropdownProps extends HTMLAttributes<HTMLDivElement | HTMLLIEl
87
94
  visible?: boolean
88
95
  }
89
96
 
97
+ const PopperManagerWrapper = ({ children, popper }: { children: ReactNode; popper: boolean }) => {
98
+ return popper ? <Manager>{children}</Manager> : <>{children}</>
99
+ }
100
+
90
101
  interface ContextProps extends CDropdownProps {
91
102
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
103
  dropdownToggleRef: RefObject<any> | undefined
93
104
  setVisible: React.Dispatch<React.SetStateAction<boolean | undefined>>
105
+ portal: boolean
94
106
  }
95
107
 
96
108
  export const CDropdownContext = createContext({} as ContextProps)
@@ -108,6 +120,7 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
108
120
  onShow,
109
121
  placement = 'bottom-start',
110
122
  popper = true,
123
+ portal = false,
111
124
  variant = 'btn-group',
112
125
  component = 'div',
113
126
  visible = false,
@@ -135,6 +148,7 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
135
148
  dropdownToggleRef,
136
149
  placement: placement,
137
150
  popper,
151
+ portal: portal,
138
152
  variant,
139
153
  visible: _visible,
140
154
  setVisible,
@@ -149,38 +163,31 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
149
163
  !_visible && onHide && onHide()
150
164
  }, [_visible])
151
165
 
152
- const DropdownContent = () => {
153
- return variant === 'input-group' ? (
154
- <>{children}</>
155
- ) : (
156
- <Component
157
- className={classNames(
158
- variant === 'nav-item' ? 'nav-item dropdown' : variant,
159
- {
160
- 'dropdown-center': direction === 'center',
161
- 'dropup dropup-center': direction === 'dropup-center',
162
- direction: direction && direction !== 'center' && direction !== 'dropup-center',
163
- show: _visible,
164
- },
165
- className,
166
- )}
167
- {...rest}
168
- ref={forkedRef}
169
- >
170
- {children}
171
- </Component>
172
- )
173
- }
174
-
175
166
  return (
176
167
  <CDropdownContext.Provider value={contextValues}>
177
- {popper ? (
178
- <Manager>
179
- <DropdownContent />
180
- </Manager>
181
- ) : (
182
- <DropdownContent />
183
- )}
168
+ <PopperManagerWrapper popper={popper}>
169
+ {variant === 'input-group' ? (
170
+ <>{children}</>
171
+ ) : (
172
+ <Component
173
+ className={classNames(
174
+ variant === 'nav-item' ? 'nav-item dropdown' : variant,
175
+ {
176
+ 'dropdown-center': direction === 'center',
177
+ 'dropup dropup-center': direction === 'dropup-center',
178
+ [`${direction}`]:
179
+ direction && direction !== 'center' && direction !== 'dropup-center',
180
+ show: _visible,
181
+ },
182
+ className,
183
+ )}
184
+ {...rest}
185
+ ref={forkedRef}
186
+ >
187
+ {children}
188
+ </Component>
189
+ )}
190
+ </PopperManagerWrapper>
184
191
  </CDropdownContext.Provider>
185
192
  )
186
193
  },
@@ -212,6 +219,7 @@ CDropdown.propTypes = {
212
219
  onShow: PropTypes.func,
213
220
  placement: placementPropType,
214
221
  popper: PropTypes.bool,
222
+ portal: PropTypes.bool,
215
223
  variant: PropTypes.oneOf(['btn-group', 'dropdown', 'input-group', 'nav-item']),
216
224
  visible: PropTypes.bool,
217
225
  }
@@ -4,6 +4,7 @@ import classNames from 'classnames'
4
4
  import { Popper, PopperChildrenProps } from 'react-popper'
5
5
 
6
6
  import { Alignments, CDropdownContext } from './CDropdown'
7
+ import { CConditionalPortal } from '../conditional-portal'
7
8
 
8
9
  import type { Placements } from '../../types'
9
10
 
@@ -30,6 +31,21 @@ export interface CDropdownMenuProps
30
31
  component?: string | ElementType
31
32
  }
32
33
 
34
+ const alignmentClassNames = (alignment: Alignments) => {
35
+ const classNames: string[] = []
36
+ if (typeof alignment === 'object') {
37
+ Object.keys(alignment).map((key) => {
38
+ classNames.push(`dropdown-menu${key === 'xs' ? '' : `-${key}`}-${alignment[key]}`)
39
+ })
40
+ }
41
+
42
+ if (typeof alignment === 'string') {
43
+ classNames.push(`dropdown-menu-${alignment}`)
44
+ }
45
+
46
+ return classNames
47
+ }
48
+
33
49
  export const CDropdownMenu: FC<CDropdownMenuProps> = ({
34
50
  children,
35
51
  className,
@@ -44,6 +60,7 @@ export const CDropdownMenu: FC<CDropdownMenuProps> = ({
44
60
  dropdownToggleRef,
45
61
  placement,
46
62
  popper,
63
+ portal,
47
64
  visible,
48
65
  setVisible,
49
66
  } = useContext(CDropdownContext)
@@ -111,48 +128,35 @@ export const CDropdownMenu: FC<CDropdownMenuProps> = ({
111
128
  _placement = 'bottom-end'
112
129
  }
113
130
 
114
- const alignmentClassNames = (alignment: Alignments) => {
115
- const classNames: string[] = []
116
- if (typeof alignment === 'object') {
117
- Object.keys(alignment).map((key) => {
118
- classNames.push(`dropdown-menu${key === 'xs' ? '' : `-${key}`}-${alignment[key]}`)
119
- })
120
- }
121
-
122
- if (typeof alignment === 'string') {
123
- classNames.push(`dropdown-menu-${alignment}`)
124
- }
125
-
126
- return classNames
127
- }
128
-
129
131
  const dropdownMenuComponent = (style?: React.CSSProperties, ref?: React.Ref<HTMLDivElement>) => (
130
- <Component
131
- className={classNames(
132
- 'dropdown-menu',
133
- {
134
- 'dropdown-menu-dark': dark,
135
- show: visible,
136
- },
137
- alignment && alignmentClassNames(alignment),
138
- className,
139
- )}
140
- ref={ref}
141
- style={style}
142
- role="menu"
143
- aria-hidden={!visible}
144
- {...(!popper && { 'data-coreui-popper': 'static' })}
145
- {...rest}
146
- >
147
- {Component === 'ul'
148
- ? React.Children.map(children, (child, index) => {
149
- if (React.isValidElement(child)) {
150
- return <li key={index}>{React.cloneElement(child)}</li>
151
- }
152
- return
153
- })
154
- : children}
155
- </Component>
132
+ <CConditionalPortal portal={portal ?? false}>
133
+ <Component
134
+ className={classNames(
135
+ 'dropdown-menu',
136
+ {
137
+ 'dropdown-menu-dark': dark,
138
+ show: visible,
139
+ },
140
+ alignment && alignmentClassNames(alignment),
141
+ className,
142
+ )}
143
+ ref={ref}
144
+ style={style}
145
+ role="menu"
146
+ aria-hidden={!visible}
147
+ {...(!popper && { 'data-coreui-popper': 'static' })}
148
+ {...rest}
149
+ >
150
+ {Component === 'ul'
151
+ ? React.Children.map(children, (child, index) => {
152
+ if (React.isValidElement(child)) {
153
+ return <li key={index}>{React.cloneElement(child)}</li>
154
+ }
155
+ return
156
+ })
157
+ : children}
158
+ </Component>
159
+ </CConditionalPortal>
156
160
  )
157
161
 
158
162
  return popper && visible ? (
@@ -112,7 +112,7 @@ export const CFormCheck = forwardRef<HTMLInputElement, CFormCheckProps>(
112
112
  if (inputRef.current && indeterminate) {
113
113
  inputRef.current.indeterminate = indeterminate
114
114
  }
115
- }, [indeterminate])
115
+ }, [indeterminate, inputRef.current])
116
116
 
117
117
  const FormControl = () => (
118
118
  <input
@@ -80,11 +80,9 @@ export const COffcanvas = forwardRef<HTMLDivElement, COffcanvasProps>(
80
80
  }, [visible])
81
81
 
82
82
  useEffect(() => {
83
- if (_visible) {
84
- if (!scroll) {
85
- document.body.style.overflow = 'hidden'
86
- document.body.style.paddingRight = '0px'
87
- }
83
+ if (_visible && !scroll) {
84
+ document.body.style.overflow = 'hidden'
85
+ document.body.style.paddingRight = '0px'
88
86
  return
89
87
  }
90
88
 
@@ -8,7 +8,7 @@ import { Transition } from 'react-transition-group'
8
8
  import { triggerPropType } from '../../props'
9
9
  import type { Triggers } from '../../types'
10
10
 
11
- export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
11
+ export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'content'> {
12
12
  /**
13
13
  * A string of all className you want applied to the component.
14
14
  */
@@ -8,7 +8,7 @@ import { Transition } from 'react-transition-group'
8
8
  import { triggerPropType } from '../../props'
9
9
  import type { Triggers } from '../../types'
10
10
 
11
- export interface CTooltipProps extends HTMLAttributes<HTMLDivElement> {
11
+ export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {
12
12
  /**
13
13
  * A string of all className you want applied to the component.
14
14
  */
@@ -1,12 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- export type Breakpoints = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
3
- export type Colors = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string;
4
- export declare const colorPropType: PropTypes.Requireable<string>;
5
- export type Placements = 'auto' | 'auto-start' | 'auto-end' | 'top-end' | 'top' | 'top-start' | 'bottom-end' | 'bottom' | 'bottom-start' | 'right-start' | 'right' | 'right-end' | 'left-start' | 'left' | 'left-end' | undefined;
6
- export declare const placementPropType: PropTypes.Requireable<Placements>;
7
- export type Shapes = 'rounded' | 'rounded-top' | 'rounded-end' | 'rounded-bottom' | 'rounded-start' | 'rounded-circle' | 'rounded-pill' | 'rounded-0' | 'rounded-1' | 'rounded-2' | 'rounded-3' | string;
8
- export declare const shapePropType: PropTypes.Requireable<string>;
9
- export type TextColors = Colors | 'white' | 'muted' | 'high-emphasis' | 'medium-emphasis' | 'disabled' | 'high-emphasis-inverse' | 'medium-emphasis-inverse' | 'disabled-inverse' | string;
10
- export declare const textColorsPropType: PropTypes.Requireable<string>;
11
- export type Triggers = 'hover' | 'focus' | 'click';
12
- export declare const triggerPropType: PropTypes.Requireable<Triggers>;
@@ -1,20 +0,0 @@
1
- import React, { forwardRef } from 'react'
2
- import PropTypes from 'prop-types'
3
-
4
- import { CCollapse, CCollapseProps } from '../collapse/CCollapse'
5
-
6
- export const CAccordionCollapse = forwardRef<HTMLDivElement, Omit<CCollapseProps, 'horizontal'>>(
7
- ({ children, ...props }, ref) => {
8
- return (
9
- <CCollapse className="accordion-collapse" {...props} ref={ref}>
10
- {children}
11
- </CCollapse>
12
- )
13
- },
14
- )
15
-
16
- CAccordionCollapse.propTypes = {
17
- children: PropTypes.node,
18
- }
19
-
20
- CAccordionCollapse.displayName = 'CAccordionCollapse'
@@ -1,10 +0,0 @@
1
- import React from 'react'
2
- import { render } from '@testing-library/react'
3
- import '@testing-library/jest-dom/extend-expect'
4
- import { CAccordionCollapse } from '../../../index'
5
-
6
- test('loads and displays CAccordionCollapse component', async () => {
7
- const { container } = render(<CAccordionCollapse>Test</CAccordionCollapse>)
8
- expect(container.firstChild).toHaveClass('accordion-collapse')
9
- expect(container).toMatchSnapshot()
10
- })
File without changes