@coreui/react-pro 5.5.0 → 5.6.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 (79) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/components/breadcrumb/CBreadcrumbItem.d.ts +9 -2
  3. package/dist/cjs/components/breadcrumb/CBreadcrumbItem.js +2 -2
  4. package/dist/cjs/components/breadcrumb/CBreadcrumbItem.js.map +1 -1
  5. package/dist/cjs/components/form/CFormSelect.d.ts +1 -0
  6. package/dist/cjs/components/form/CFormSelect.js.map +1 -1
  7. package/dist/cjs/components/grid/CRow.js +1 -1
  8. package/dist/cjs/components/grid/CRow.js.map +1 -1
  9. package/dist/cjs/components/picker/CPicker.js +1 -0
  10. package/dist/cjs/components/picker/CPicker.js.map +1 -1
  11. package/dist/cjs/components/smart-table/CSmartTable.js +81 -66
  12. package/dist/cjs/components/smart-table/CSmartTable.js.map +1 -1
  13. package/dist/cjs/components/smart-table/CSmartTableBody.js +1 -0
  14. package/dist/cjs/components/smart-table/CSmartTableBody.js.map +1 -1
  15. package/dist/cjs/components/smart-table/CSmartTableHead.d.ts +1 -1
  16. package/dist/cjs/components/smart-table/CSmartTableHead.js +4 -1
  17. package/dist/cjs/components/smart-table/CSmartTableHead.js.map +1 -1
  18. package/dist/cjs/components/smart-table/CSmartTableInterface.d.ts +5 -4
  19. package/dist/cjs/components/smart-table/types.d.ts +5 -4
  20. package/dist/cjs/components/smart-table/utils.d.ts +12 -18
  21. package/dist/cjs/components/smart-table/utils.js +104 -96
  22. package/dist/cjs/components/smart-table/utils.js.map +1 -1
  23. package/dist/cjs/components/tabs/CTab.d.ts +4 -0
  24. package/dist/cjs/components/tabs/CTab.js +1 -0
  25. package/dist/cjs/components/tabs/CTab.js.map +1 -1
  26. package/dist/cjs/components/toast/CToast.d.ts +1 -1
  27. package/dist/cjs/components/toast/CToast.js +6 -3
  28. package/dist/cjs/components/toast/CToast.js.map +1 -1
  29. package/dist/cjs/components/toast/CToaster.js +1 -1
  30. package/dist/cjs/components/toast/CToaster.js.map +1 -1
  31. package/dist/cjs/utils/index.d.ts +2 -1
  32. package/dist/cjs/utils/isEqual.d.ts +2 -0
  33. package/dist/esm/components/breadcrumb/CBreadcrumbItem.d.ts +9 -2
  34. package/dist/esm/components/breadcrumb/CBreadcrumbItem.js +2 -2
  35. package/dist/esm/components/breadcrumb/CBreadcrumbItem.js.map +1 -1
  36. package/dist/esm/components/form/CFormSelect.d.ts +1 -0
  37. package/dist/esm/components/form/CFormSelect.js.map +1 -1
  38. package/dist/esm/components/grid/CRow.js +2 -2
  39. package/dist/esm/components/grid/CRow.js.map +1 -1
  40. package/dist/esm/components/picker/CPicker.js +1 -0
  41. package/dist/esm/components/picker/CPicker.js.map +1 -1
  42. package/dist/esm/components/smart-table/CSmartTable.js +82 -67
  43. package/dist/esm/components/smart-table/CSmartTable.js.map +1 -1
  44. package/dist/esm/components/smart-table/CSmartTableBody.js +1 -0
  45. package/dist/esm/components/smart-table/CSmartTableBody.js.map +1 -1
  46. package/dist/esm/components/smart-table/CSmartTableHead.d.ts +1 -1
  47. package/dist/esm/components/smart-table/CSmartTableHead.js +4 -1
  48. package/dist/esm/components/smart-table/CSmartTableHead.js.map +1 -1
  49. package/dist/esm/components/smart-table/CSmartTableInterface.d.ts +5 -4
  50. package/dist/esm/components/smart-table/types.d.ts +5 -4
  51. package/dist/esm/components/smart-table/utils.d.ts +12 -18
  52. package/dist/esm/components/smart-table/utils.js +104 -98
  53. package/dist/esm/components/smart-table/utils.js.map +1 -1
  54. package/dist/esm/components/tabs/CTab.d.ts +4 -0
  55. package/dist/esm/components/tabs/CTab.js +1 -0
  56. package/dist/esm/components/tabs/CTab.js.map +1 -1
  57. package/dist/esm/components/toast/CToast.d.ts +1 -1
  58. package/dist/esm/components/toast/CToast.js +6 -3
  59. package/dist/esm/components/toast/CToast.js.map +1 -1
  60. package/dist/esm/components/toast/CToaster.js +1 -1
  61. package/dist/esm/components/toast/CToaster.js.map +1 -1
  62. package/dist/esm/utils/index.d.ts +2 -1
  63. package/dist/esm/utils/isEqual.d.ts +2 -0
  64. package/package.json +9 -9
  65. package/src/components/breadcrumb/CBreadcrumbItem.tsx +36 -21
  66. package/src/components/form/CFormSelect.tsx +1 -0
  67. package/src/components/grid/CRow.tsx +1 -1
  68. package/src/components/picker/CPicker.tsx +1 -0
  69. package/src/components/smart-table/CSmartTable.tsx +94 -71
  70. package/src/components/smart-table/CSmartTableBody.tsx +2 -1
  71. package/src/components/smart-table/CSmartTableHead.tsx +5 -2
  72. package/src/components/smart-table/CSmartTableInterface.tsx +5 -4
  73. package/src/components/smart-table/types.ts +5 -4
  74. package/src/components/smart-table/utils.ts +154 -123
  75. package/src/components/tabs/CTab.tsx +5 -0
  76. package/src/components/toast/CToast.tsx +7 -4
  77. package/src/components/toast/CToaster.tsx +1 -1
  78. package/src/utils/index.ts +2 -0
  79. package/src/utils/isEqual.ts +58 -0
@@ -14,26 +14,31 @@ export const filterColumns = (
14
14
  columnFilter: boolean | ColumnFilter | undefined,
15
15
  columnFilterState: ColumnFilterValue,
16
16
  itemsDataColumns: string[],
17
- ) => {
17
+ ): Item[] => {
18
18
  if (columnFilter && typeof columnFilter === 'object' && columnFilter.external) {
19
19
  return items
20
20
  }
21
21
 
22
- Object.entries(columnFilterState).forEach(([key, value]) => {
23
- if (value instanceof Function) {
24
- items = items.filter((item) => value(item[key]))
25
- return
26
- }
22
+ if (Object.entries(columnFilterState).length === 0) {
23
+ return items
24
+ }
27
25
 
28
- const columnFilter = String(value).toLowerCase()
29
- if (columnFilter && itemsDataColumns.includes(key)) {
30
- items = items.filter((item) => {
31
- return String(item[key]).toLowerCase().includes(columnFilter)
32
- })
26
+ let filteredItems = [...items]
27
+
28
+ for (const [key, value] of Object.entries(columnFilterState)) {
29
+ if (typeof value === 'function') {
30
+ filteredItems = filteredItems.filter((item) => value(item[key]))
31
+ } else {
32
+ const columnFilterValue = String(value).toLowerCase()
33
+ if (columnFilterValue && itemsDataColumns.includes(key)) {
34
+ filteredItems = filteredItems.filter((item) =>
35
+ String(item[key]).toLowerCase().includes(columnFilterValue),
36
+ )
37
+ }
33
38
  }
34
- })
39
+ }
35
40
 
36
- return items
41
+ return filteredItems
37
42
  }
38
43
 
39
44
  export const filterTable = (
@@ -41,7 +46,7 @@ export const filterTable = (
41
46
  tableFilter: boolean | TableFilter | undefined,
42
47
  tableFilterState: string,
43
48
  itemsDataColumns: string[],
44
- ) => {
49
+ ): Item[] => {
45
50
  if (
46
51
  !tableFilterState ||
47
52
  (tableFilter && typeof tableFilter === 'object' && tableFilter.external)
@@ -50,43 +55,46 @@ export const filterTable = (
50
55
  }
51
56
 
52
57
  const filter = tableFilterState.toLowerCase()
53
- const valueContainFilter = (val: any) => String(val).toLowerCase().includes(filter)
54
- items = items.filter((item) => {
55
- return !!itemsDataColumns.find((key) => valueContainFilter(item[key]))
56
- })
57
58
 
58
- return items
59
+ return items.filter((item) =>
60
+ itemsDataColumns.some((key) => String(item[key]).toLowerCase().includes(filter)),
61
+ )
59
62
  }
60
63
 
61
64
  export const getClickedColumnName = (
62
- target: HTMLTextAreaElement,
65
+ target: HTMLElement,
63
66
  columnNames: string[],
64
- selectable: boolean | undefined
67
+ selectable?: boolean,
65
68
  ): string => {
66
- const closest = target.closest('tr')
67
- const children = closest ? Array.from(closest.children) : []
68
- const clickedCell = children.filter((child) => child.contains(target))[0]
69
- return selectable ? columnNames[children.indexOf(clickedCell) - 1] : columnNames[children.indexOf(clickedCell)]
70
- }
69
+ const clickedCell = target.closest('td')
70
+ if (!clickedCell) {
71
+ return ''
72
+ }
71
73
 
72
- export const getColumnKey = (column: Column | string) =>
73
- typeof column === 'object' ? column.key : column
74
+ const row = clickedCell.closest('tr')
75
+ if (!row) {
76
+ return ''
77
+ }
74
78
 
75
- export const getColumnLabel = (column: Column | string) =>
76
- typeof column === 'object'
77
- ? column.label !== undefined
78
- ? column.label
79
- : pretifyName(column.key)
80
- : pretifyName(column)
79
+ const cells = Array.from(row.children)
80
+ let index = cells.indexOf(clickedCell)
81
81
 
82
- export const getColumnName = (column: string | Column) => {
83
- if (typeof column === 'object') {
84
- return column.key
82
+ if (selectable) {
83
+ index -= 1
85
84
  }
86
85
 
87
- return column
86
+ return columnNames[index] || ''
88
87
  }
89
88
 
89
+ export const getColumnKey = (column: Column | string): string =>
90
+ typeof column === 'object' ? column.key : column
91
+
92
+ export const getColumnLabel = (column: Column | string): string =>
93
+ typeof column === 'object' ? (column.label ?? pretifyName(column.key)) : pretifyName(column)
94
+
95
+ export const getColumnName = (column: Column | string): string =>
96
+ typeof column === 'object' ? column.key : column
97
+
90
98
  export const getColumnNames = (
91
99
  columns: (string | Column)[] | undefined,
92
100
  items: Item[],
@@ -128,23 +136,22 @@ export const getColumns = (_columns: (Column | Group | string)[]): (Column | str
128
136
  return columns
129
137
  }
130
138
 
131
- export const countColumns = (columns: Column[], counter = 0) => {
132
- let _counter = counter
133
- for (const column of columns) {
134
- if (!column.children) {
135
- _counter++
136
- }
139
+ export const countColumns = (columns: Column[]): number => {
140
+ let count = 0
137
141
 
138
- if (column.children) {
139
- _counter = countColumns(column.children, _counter)
142
+ for (const column of columns) {
143
+ if (!column.children || column.children.length === 0) {
144
+ count++
145
+ } else {
146
+ count += countColumns(column.children)
140
147
  }
141
148
  }
142
149
 
143
- return _counter
150
+ return count
144
151
  }
145
152
 
146
- export const getColumnGroups = (columns: (string | Column)[] | undefined) => {
147
- const groups = []
153
+ export const getColumnGroups = (columns: (string | Column)[] | undefined): Group[][] => {
154
+ const groups: Group[][] = []
148
155
 
149
156
  const traverseColumns = (column: Column, deep = 0, colSpan = 0): Group[] => {
150
157
  const groups = []
@@ -205,103 +212,96 @@ export const getColumnGroups = (columns: (string | Column)[] | undefined) => {
205
212
  return groups
206
213
  }
207
214
 
208
- export const getColumnNamesFromItems = (items: Item[]) =>
215
+ export const getColumnNamesFromItems = (items: Item[]): string[] =>
209
216
  Object.keys(items[0] || {}).filter((el) => el.charAt(0) !== '_')
210
217
 
211
- export const getColumnSorterState = (
212
- key: string,
213
- sorterState: SorterValue | undefined,
214
- ): string | number => {
215
- if (sorterState && sorterState.column === key) {
216
- if (sorterState.state) {
217
- return sorterState.state
218
- }
219
- return 0
218
+ export const getColumnSorterFunction = (column: Column | undefined) => {
219
+ if (
220
+ column &&
221
+ typeof column === 'object' &&
222
+ column.sorter &&
223
+ typeof column.sorter === 'function'
224
+ ) {
225
+ return column.sorter
220
226
  }
221
227
 
222
- return 0
223
- }
224
-
225
- export const getColumnValues = (items: Item[], key: string) => {
226
- return items.map((item) => item[key])
228
+ return
227
229
  }
228
230
 
229
- export const getTableDataCellProps = (column: Column | string, item: Item, colName: string) => {
230
- const props = {}
231
+ export const getColumnSorterState = (key: string, sorterState?: SorterValue[]): string | number => {
232
+ const state = sorterState && sorterState.find((el) => el.column === key)
231
233
 
232
- if (typeof column === 'object' && column._colProps) {
233
- Object.assign(props, column._colProps)
234
- }
234
+ return state ? state.state : 0
235
+ }
235
236
 
236
- if (item._cellProps && item._cellProps['all']) {
237
- Object.assign(props, item._cellProps['all'])
238
- }
237
+ export const getColumnValues = (items: Item[], key: string): any[] => items.map((item) => item[key])
239
238
 
240
- if (item._cellProps && item._cellProps[colName]) {
241
- Object.assign(props, item._cellProps[colName])
239
+ export const getTableDataCellProps = (
240
+ column: Column | string,
241
+ item: Item,
242
+ colName: string,
243
+ ): Record<string, any> => {
244
+ const props = {
245
+ ...(typeof column === 'object' && column._colProps),
246
+ ...item._cellProps?.all,
247
+ ...item._cellProps?.[colName],
242
248
  }
243
249
 
244
250
  return props
245
251
  }
246
252
 
247
- export const getTableDataCellStyles = (column: Column | string, item: Item, colName: string) => {
248
- const styles = {}
249
-
250
- if (typeof column === 'object' && column._colStyle) {
251
- Object.assign(styles, column._colStyle)
252
- }
253
-
254
- if (item._cellStyle && item._cellStyle['all']) {
255
- Object.assign(styles, item._cellStyle['all'])
256
- }
257
-
258
- if (item._cellStyle && item._cellStyle[colName]) {
259
- Object.assign(styles, item._cellStyle[colName])
253
+ export const getTableDataCellStyles = (
254
+ column: Column | string,
255
+ item: Item,
256
+ colName: string,
257
+ ): Record<string, any> => {
258
+ const styles = {
259
+ ...(typeof column === 'object' && column._colStyle),
260
+ ...item._cellStyle?.all,
261
+ ...item._cellStyle?.[colName],
260
262
  }
261
263
 
262
264
  return styles
263
265
  }
264
266
 
265
- export const getTableHeaderCellProps = (column: Column | string) => {
266
- if (typeof column === 'object' && column._props) {
267
- return column._props
268
- }
269
-
270
- return {}
271
- }
267
+ export const getTableHeaderCellProps = (column: Column | string) =>
268
+ typeof column === 'object' && column._props ? column._props : {}
272
269
 
273
270
  export const getTableHeaderCellStyles = (
274
271
  column: Column | string,
275
272
  columnSorter: boolean | Sorter | undefined,
276
- ) => {
277
- const style = {}
273
+ ): Record<string, any> => {
274
+ const style: Record<string, any> = {}
278
275
 
279
- if (
276
+ const isSortable =
280
277
  columnSorter &&
281
278
  (typeof column !== 'object' ||
282
279
  (typeof column === 'object' && (column.sorter === undefined || column.sorter)))
283
- ) {
284
- (style as { [key: string]: string })['cursor'] = 'pointer'
280
+
281
+ if (isSortable) {
282
+ style.cursor = 'pointer'
285
283
  }
286
284
 
287
285
  if (typeof column === 'object' && column._style) {
288
- return { ...style, ...column._style }
286
+ Object.assign(style, column._style)
289
287
  }
288
+
290
289
  return style
291
290
  }
292
291
 
293
292
  export const isSortable = (
294
- i: number,
293
+ index: number,
295
294
  columns: (string | Column)[] | undefined,
296
- columnSorter: Sorter | boolean | undefined,
295
+ columnSorter: boolean | Sorter | undefined,
297
296
  itemsDataColumns: string[],
298
297
  columnNames: string[],
299
- ): boolean | undefined => {
300
- const isDataColumn = itemsDataColumns.includes(columnNames[i])
301
- let column
302
- if (columns) column = columns[i]
298
+ ): boolean => {
299
+ const key = columnNames[index]
300
+ const isDataColumn = itemsDataColumns.includes(key)
301
+ const column = columns ? columns[index] : undefined
302
+
303
303
  return (
304
- columnSorter &&
304
+ !!columnSorter &&
305
305
  (!columns ||
306
306
  typeof column !== 'object' ||
307
307
  (typeof column === 'object' && (column.sorter === undefined || column.sorter))) &&
@@ -309,7 +309,7 @@ export const isSortable = (
309
309
  )
310
310
  }
311
311
 
312
- export const pretifyName = (name: string) => {
312
+ export const pretifyName = (name: string): string => {
313
313
  return name
314
314
  .replace(/[-_.]/g, ' ')
315
315
  .replace(/ +/g, ' ')
@@ -319,28 +319,59 @@ export const pretifyName = (name: string) => {
319
319
  .join(' ')
320
320
  }
321
321
 
322
+ export const sortBy = (
323
+ column: Column | undefined,
324
+ items: Item[],
325
+ key: string,
326
+ order: SorterValue['state'],
327
+ ): Item[] => {
328
+ const sorterFunction = getColumnSorterFunction(column)
329
+
330
+ const sortedItems = [...items].sort(
331
+ sorterFunction ||
332
+ ((a, b) => {
333
+ const valA = a[key]
334
+ const valB = b[key]
335
+ const aValue = typeof valA === 'number' ? valA : String(valA).toLowerCase()
336
+ const bValue = typeof valB === 'number' ? valB : String(valB).toLowerCase()
337
+ return aValue > bValue ? 1 : bValue > aValue ? -1 : 0
338
+ }),
339
+ )
340
+
341
+ return order === 'desc' ? sortedItems.reverse() : sortedItems
342
+ }
343
+
322
344
  export const sortItems = (
345
+ columns: (Column | string)[] | undefined,
323
346
  columnSorter: boolean | Sorter | undefined,
324
347
  items: Item[],
325
348
  itemsDataColumns: string[],
326
- sorterState: SorterValue,
327
- ) => {
328
- const column = sorterState.column
349
+ sorterState: SorterValue[],
350
+ ): Item[] => {
329
351
  if (
330
- !column ||
331
- !itemsDataColumns.includes(column) ||
332
- (columnSorter && typeof columnSorter === 'object' && columnSorter.external)
352
+ (columnSorter && typeof columnSorter === 'object' && columnSorter.external) ||
353
+ sorterState.length === 0
333
354
  ) {
334
355
  return items
335
356
  }
336
357
 
337
- const flip = sorterState.state === 'asc' ? 1 : sorterState.state === 'desc' ? -1 : 0
338
- const sorted = items.slice().sort((item, item2) => {
339
- const value = item[column]
340
- const value2 = item2[column]
341
- const a = typeof value === 'number' ? value : String(value).toLowerCase()
342
- const b = typeof value2 === 'number' ? value2 : String(value2).toLowerCase()
343
- return a > b ? 1 * flip : b > a ? -1 * flip : 0
344
- })
345
- return sorted
358
+ let sortedItems = [...items]
359
+
360
+ for (const sorter of [...sorterState].reverse()) {
361
+ const key = sorter.column
362
+ const order = sorter.state
363
+ const column =
364
+ columns &&
365
+ (columns.find((column) => typeof column === 'object' && column.key === key) as
366
+ | Column
367
+ | undefined)
368
+
369
+ if (!key || !itemsDataColumns.includes(key)) {
370
+ continue
371
+ }
372
+
373
+ sortedItems = sortBy(column, sortedItems, key, order)
374
+ }
375
+
376
+ return sortedItems
346
377
  }
@@ -9,6 +9,10 @@ export interface CTabProps extends HTMLAttributes<HTMLButtonElement> {
9
9
  * A string of all className you want applied to the base component.
10
10
  */
11
11
  className?: string
12
+ /**
13
+ * Toggle the disabled state for the component.
14
+ */
15
+ disabled?: boolean
12
16
  /**
13
17
  * Item key.
14
18
  */
@@ -50,6 +54,7 @@ export const CTab = forwardRef<HTMLButtonElement, CTabProps>(
50
54
  CTab.propTypes = {
51
55
  children: PropTypes.node,
52
56
  className: PropTypes.string,
57
+ disabled: PropTypes.bool,
53
58
  itemKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
54
59
  }
55
60
 
@@ -44,7 +44,7 @@ export interface CToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title
44
44
  /**
45
45
  * @ignore
46
46
  */
47
- key?: number
47
+ innerKey?: number | string
48
48
  /**
49
49
  * Callback fired when the component requests to be closed.
50
50
  */
@@ -76,7 +76,7 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
76
76
  color,
77
77
  delay = 5000,
78
78
  index,
79
- key,
79
+ innerKey,
80
80
  visible = false,
81
81
  onClose,
82
82
  onShow,
@@ -143,7 +143,7 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
143
143
  onMouseEnter={() => clearTimeout(timeout.current)}
144
144
  onMouseLeave={() => _autohide()}
145
145
  {...rest}
146
- key={key}
146
+ key={innerKey}
147
147
  ref={forkedRef}
148
148
  >
149
149
  {children}
@@ -163,7 +163,10 @@ CToast.propTypes = {
163
163
  color: colorPropType,
164
164
  delay: PropTypes.number,
165
165
  index: PropTypes.number,
166
- key: PropTypes.number,
166
+ innerKey: PropTypes.oneOfType([
167
+ PropTypes.number,
168
+ PropTypes.string
169
+ ]),
167
170
  onClose: PropTypes.func,
168
171
  onShow: PropTypes.func,
169
172
  visible: PropTypes.bool,
@@ -45,7 +45,7 @@ export const CToaster = forwardRef<HTMLDivElement, CToasterProps>(
45
45
  ...state,
46
46
  React.cloneElement(push, {
47
47
  index: index.current,
48
- key: index.current,
48
+ innerKey: index.current,
49
49
  onClose: (index: number) =>
50
50
  setToasts((state) => state.filter((i) => i.props.index !== index)),
51
51
  }),
@@ -2,6 +2,7 @@ import executeAfterTransition from './executeAfterTransition'
2
2
  import getNextActiveElement from './getNextActiveElement'
3
3
  import getRTLPlacement from './getRTLPlacement'
4
4
  import getTransitionDurationFromElement from './getTransitionDurationFromElement'
5
+ import isEqual from './isEqual'
5
6
  import isInViewport from './isInViewport'
6
7
  import isObjectInArray from './isObjectInArray'
7
8
  import isRTL from './isRTL'
@@ -11,6 +12,7 @@ export {
11
12
  getNextActiveElement,
12
13
  getRTLPlacement,
13
14
  getTransitionDurationFromElement,
15
+ isEqual,
14
16
  isInViewport,
15
17
  isObjectInArray,
16
18
  isRTL,
@@ -0,0 +1,58 @@
1
+ const isEqual = (a: any, b: any): boolean => {
2
+ if (a === b) return true
3
+
4
+ if (a && b && typeof a === 'object' && typeof b === 'object') {
5
+ if (a.constructor !== b.constructor) return false
6
+
7
+ let length: number, i: number | [any, any], keys: string[]
8
+ if (Array.isArray(a)) {
9
+ length = a.length
10
+ if (length !== b.length) return false
11
+ for (i = length; i-- !== 0; ) if (!isEqual(a[i], b[i])) return false
12
+ return true
13
+ }
14
+
15
+ if (a instanceof Map && b instanceof Map) {
16
+ if (a.size !== b.size) return false
17
+ for (i of a.entries()) if (!b.has(i[0])) return false
18
+ for (i of a.entries()) if (!isEqual(i[1], b.get(i[0]))) return false
19
+ return true
20
+ }
21
+
22
+ if (a instanceof Set && b instanceof Set) {
23
+ if (a.size !== b.size) return false
24
+ for (i of a.entries()) if (!b.has(i[0])) return false
25
+ return true
26
+ }
27
+
28
+ if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
29
+ length = a.length
30
+ if (length !== b.length) return false
31
+ for (i = length; i-- !== 0; ) if (a[i] !== b[i]) return false
32
+ return true
33
+ }
34
+
35
+ if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags
36
+ if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf()
37
+ if (a.toString !== Object.prototype.toString) return a.toString() === b.toString()
38
+
39
+ keys = Object.keys(a)
40
+ length = keys.length
41
+ if (length !== Object.keys(b).length) return false
42
+
43
+ for (i = length; i-- !== 0; )
44
+ if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false
45
+
46
+ for (i = length; i-- !== 0; ) {
47
+ var key: string = keys[i]
48
+
49
+ if (!isEqual(a[key], b[key])) return false
50
+ }
51
+
52
+ return true
53
+ }
54
+
55
+ return a !== a && b !== b
56
+ }
57
+
58
+ export default isEqual