@coreui/react-pro 4.8.0 → 4.9.0-next.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.
Files changed (166) hide show
  1. package/README.md +1 -1
  2. package/dist/components/alert/CAlert.d.ts +1 -1
  3. package/dist/components/avatar/CAvatar.d.ts +1 -1
  4. package/dist/components/badge/CBadge.d.ts +1 -1
  5. package/dist/components/button/CButton.d.ts +1 -1
  6. package/dist/components/calendar/index.d.ts +2 -0
  7. package/dist/components/calendar/utils.d.ts +22 -0
  8. package/dist/components/callout/CCallout.d.ts +1 -1
  9. package/dist/components/card/CCard.d.ts +1 -1
  10. package/dist/components/date-picker/CDatePicker.d.ts +1 -1
  11. package/dist/components/date-range-picker/CDateRangePicker.d.ts +3 -3
  12. package/dist/components/date-range-picker/utils.d.ts +1 -0
  13. package/dist/components/dropdown/CDropdown.d.ts +1 -1
  14. package/dist/components/dropdown/CDropdownToggle.d.ts +1 -1
  15. package/dist/components/element-cover/CElementCover.d.ts +0 -4
  16. package/dist/components/element-cover/index.d.ts +2 -0
  17. package/dist/components/form/CFormCheck.d.ts +1 -1
  18. package/dist/components/index.d.ts +1 -0
  19. package/dist/components/list-group/CListGroupItem.d.ts +4 -5
  20. package/dist/components/multi-select/CMultiSelect.d.ts +1 -13
  21. package/dist/components/multi-select/CMultiSelectNativeSelect.d.ts +1 -1
  22. package/dist/components/multi-select/CMultiSelectOptions.d.ts +1 -1
  23. package/dist/components/multi-select/CMultiSelectSelection.d.ts +1 -1
  24. package/dist/components/multi-select/types.d.ts +14 -0
  25. package/dist/components/multi-select/utils.d.ts +6 -0
  26. package/dist/components/navbar/CNavbar.d.ts +1 -1
  27. package/dist/components/offcanvas/COffcanvas.d.ts +7 -1
  28. package/dist/components/picker/CPicker.d.ts +1 -1
  29. package/dist/components/placeholder/CPlaceholder.d.ts +1 -1
  30. package/dist/components/popover/CPopover.d.ts +1 -1
  31. package/dist/components/progress/CProgressBar.d.ts +1 -1
  32. package/dist/components/smart-table/CSmartTableBody.d.ts +6 -5
  33. package/dist/components/smart-table/CSmartTableHead.d.ts +6 -3
  34. package/dist/components/smart-table/CSmartTableInterface.d.ts +38 -59
  35. package/dist/components/smart-table/types.d.ts +53 -0
  36. package/dist/components/smart-table/utils.d.ts +16 -0
  37. package/dist/components/spinner/CSpinner.d.ts +1 -1
  38. package/dist/components/table/CTable.d.ts +2 -18
  39. package/dist/components/table/CTableBody.d.ts +1 -1
  40. package/dist/components/table/CTableDataCell.d.ts +1 -1
  41. package/dist/components/table/CTableFoot.d.ts +1 -1
  42. package/dist/components/table/CTableHead.d.ts +1 -1
  43. package/dist/components/table/CTableHeaderCell.d.ts +1 -1
  44. package/dist/components/table/CTableRow.d.ts +1 -1
  45. package/dist/components/table/types.d.ts +17 -0
  46. package/dist/components/table/utils.d.ts +5 -0
  47. package/dist/components/time-picker/types.d.ts +15 -0
  48. package/dist/components/time-picker/utils.d.ts +23 -0
  49. package/dist/components/toast/CToast.d.ts +1 -1
  50. package/dist/components/toast/CToastClose.d.ts +1 -1
  51. package/dist/components/tooltip/CTooltip.d.ts +1 -1
  52. package/dist/components/virtual-scroller/CVirtualScroller.d.ts +0 -8
  53. package/dist/components/widgets/CWidgetStatsA.d.ts +1 -1
  54. package/dist/components/widgets/CWidgetStatsB.d.ts +1 -1
  55. package/dist/components/widgets/CWidgetStatsC.d.ts +1 -1
  56. package/dist/components/widgets/CWidgetStatsD.d.ts +1 -1
  57. package/dist/components/widgets/CWidgetStatsF.d.ts +1 -1
  58. package/dist/hooks/index.d.ts +3 -0
  59. package/dist/hooks/useForkedRef.d.ts +7 -0
  60. package/dist/hooks/useStateWithCallback.d.ts +2 -0
  61. package/dist/index.es.js +1171 -1109
  62. package/dist/index.es.js.map +1 -1
  63. package/dist/index.js +1171 -1108
  64. package/dist/index.js.map +1 -1
  65. package/dist/props.d.ts +8 -0
  66. package/dist/types.d.ts +7 -0
  67. package/dist/utils/index.d.ts +2 -3
  68. package/dist/utils/isObjectInArray.d.ts +2 -0
  69. package/package.json +11 -11
  70. package/src/components/accordion/CAccordionBody.tsx +1 -0
  71. package/src/components/accordion/CAccordionCollapse.tsx +1 -0
  72. package/src/components/alert/CAlert.tsx +3 -2
  73. package/src/components/avatar/CAvatar.tsx +2 -8
  74. package/src/components/backdrop/CBackdrop.tsx +2 -2
  75. package/src/components/badge/CBadge.tsx +2 -10
  76. package/src/components/button/CButton.tsx +3 -1
  77. package/src/components/calendar/CCalendar.tsx +351 -240
  78. package/src/components/calendar/index.ts +3 -0
  79. package/src/{utils/calendar.ts → components/calendar/utils.ts} +1 -47
  80. package/src/components/callout/CCallout.tsx +2 -1
  81. package/src/components/card/CCard.tsx +2 -1
  82. package/src/components/carousel/CCarousel.tsx +1 -1
  83. package/src/components/carousel/CCarouselItem.tsx +1 -1
  84. package/src/components/collapse/CCollapse.tsx +1 -1
  85. package/src/components/date-picker/CDatePicker.tsx +1 -1
  86. package/src/components/date-range-picker/CDateRangePicker.tsx +4 -4
  87. package/src/components/date-range-picker/utils.ts +49 -0
  88. package/src/components/dropdown/CDropdown.tsx +3 -2
  89. package/src/components/dropdown/CDropdownItem.tsx +1 -2
  90. package/src/components/dropdown/CDropdownMenu.tsx +2 -1
  91. package/src/components/dropdown/CDropdownToggle.tsx +5 -4
  92. package/src/components/element-cover/CElementCover.tsx +16 -22
  93. package/src/components/element-cover/index.ts +3 -0
  94. package/src/components/form/CFormCheck.tsx +3 -3
  95. package/src/components/form/CFormControlValidation.tsx +0 -1
  96. package/src/components/form/CFormControlWrapper.tsx +0 -1
  97. package/src/components/form/CFormInput.tsx +8 -4
  98. package/src/components/form/CFormRange.tsx +1 -2
  99. package/src/components/form/CFormSelect.tsx +1 -2
  100. package/src/components/form/CFormTextarea.tsx +1 -2
  101. package/src/components/index.ts +1 -0
  102. package/src/components/list-group/CListGroupItem.tsx +8 -8
  103. package/src/components/list-group/CListGroupItem.tsx~HEAD +3 -1
  104. package/src/components/modal/CModal.tsx +2 -2
  105. package/src/components/modal/CModalHeader.tsx +3 -2
  106. package/src/components/multi-select/CMultiSelect.tsx +15 -74
  107. package/src/components/multi-select/CMultiSelectNativeSelect.tsx +1 -1
  108. package/src/components/multi-select/CMultiSelectOptions.tsx +2 -2
  109. package/src/components/multi-select/CMultiSelectSelection.tsx +1 -1
  110. package/src/components/multi-select/types.ts +15 -0
  111. package/src/components/multi-select/utils.ts +92 -0
  112. package/src/components/nav/CNavItem.tsx +1 -0
  113. package/src/components/nav/CNavLink.tsx +4 -3
  114. package/src/components/navbar/CNavbar.tsx +2 -1
  115. package/src/components/offcanvas/COffcanvas.tsx +38 -19
  116. package/src/components/picker/CPicker.tsx +1 -1
  117. package/src/components/placeholder/CPlaceholder.tsx +2 -1
  118. package/src/components/popover/CPopover.tsx +2 -1
  119. package/src/components/progress/CProgress.tsx +1 -0
  120. package/src/components/progress/CProgressBar.tsx +2 -1
  121. package/src/components/sidebar/CSidebar.tsx +3 -2
  122. package/src/components/smart-table/CSmartTable.tsx +263 -257
  123. package/src/components/smart-table/CSmartTableBody.tsx +98 -107
  124. package/src/components/smart-table/CSmartTableCleaner.tsx +1 -1
  125. package/src/components/smart-table/CSmartTableFilter.tsx +1 -3
  126. package/src/components/smart-table/CSmartTableHead.tsx +56 -103
  127. package/src/components/smart-table/CSmartTableInterface.tsx +49 -71
  128. package/src/components/smart-table/CSmartTableItemsPerPageSelector.tsx +1 -2
  129. package/src/components/smart-table/types.ts +65 -0
  130. package/src/components/smart-table/utils.ts +199 -0
  131. package/src/components/spinner/CSpinner.tsx +2 -1
  132. package/src/components/table/CTable.tsx +25 -59
  133. package/src/components/table/CTableBody.tsx +2 -1
  134. package/src/components/table/CTableDataCell.tsx +2 -1
  135. package/src/components/table/CTableFoot.tsx +2 -1
  136. package/src/components/table/CTableHead.tsx +2 -1
  137. package/src/components/table/CTableHeaderCell.tsx +2 -1
  138. package/src/components/table/CTableRow.tsx +2 -1
  139. package/src/components/table/types.ts +20 -0
  140. package/src/components/table/utils.ts +29 -0
  141. package/src/components/tabs/CTabPane.tsx +2 -1
  142. package/src/components/time-picker/CTimePicker.tsx +48 -23
  143. package/src/components/time-picker/CTimePickerRollCol.tsx +1 -1
  144. package/src/components/time-picker/types.ts +15 -0
  145. package/src/{utils/time.ts → components/time-picker/utils.ts} +43 -2
  146. package/src/components/toast/CToast.tsx +4 -4
  147. package/src/components/toast/CToastClose.tsx +2 -2
  148. package/src/components/toast/CToaster.tsx +2 -1
  149. package/src/components/tooltip/CTooltip.tsx +3 -2
  150. package/src/components/virtual-scroller/CVirtualScroller.tsx +32 -55
  151. package/src/components/widgets/CWidgetStatsA.tsx +3 -3
  152. package/src/components/widgets/CWidgetStatsB.tsx +4 -4
  153. package/src/components/widgets/CWidgetStatsC.tsx +4 -4
  154. package/src/components/widgets/CWidgetStatsD.tsx +4 -5
  155. package/src/components/widgets/CWidgetStatsE.tsx +1 -2
  156. package/src/components/widgets/CWidgetStatsF.tsx +3 -4
  157. package/src/{components/Types.tsx → props.ts} +1 -68
  158. package/src/types.ts +68 -0
  159. package/src/utils/index.ts +2 -3
  160. package/src/utils/isObjectInArray.ts +14 -0
  161. package/src/components/multi-select/CMultiSelectCleaner.tsx +0 -18
  162. package/src/utils/getNextSibling.ts +0 -18
  163. package/src/utils/getPreviousSibling.ts +0 -18
  164. /package/src/{utils/hooks → hooks}/index.ts +0 -0
  165. /package/src/{utils/hooks → hooks}/useForkedRef.ts +0 -0
  166. /package/src/{utils/hooks → hooks}/useStateWithCallback.ts +0 -0
@@ -1,81 +1,24 @@
1
1
  import { HTMLAttributes, MouseEvent, ReactNode } from 'react'
2
+
2
3
  import { CSmartPaginationProps } from '../smart-pagination/CSmartPagination'
3
4
  import { CTableProps } from '../table/CTable'
4
- import { CTableDataCellProps } from '../table/CTableDataCell'
5
5
  import { CTableBodyProps } from '../table/CTableBody'
6
6
  import { CTableFootProps } from '../table/CTableFoot'
7
- import { CTableHeaderCellProps } from '../table/CTableHeaderCell'
8
- import { CTableRowProps } from '../table/CTableRow'
9
7
  import { CTableHeadProps } from '../table/CTableHead'
10
8
 
11
- export interface Column {
12
- filter?: boolean | ((values: any[], onChange: (value: any) => void) => ReactNode)
13
- label?: string
14
- key: string
15
- sorter?: boolean
16
- _style?: any
17
- _props?: CTableHeaderCellProps
18
- }
19
-
20
- export interface ColumnFilter {
21
- lazy?: boolean
22
- external?: boolean
23
- }
24
-
25
- export interface ColumnFilterValue {
26
- [key: string]: any
27
- }
28
-
29
- export interface FooterItem {
30
- label?: string
31
- _props?: CTableDataCellProps
32
- }
33
-
34
- export interface Item {
35
- [key: string]: number | string | any
36
- _cellProps?: any
37
- _props?: CTableRowProps
38
- _selected?: boolean
39
- }
40
-
41
- export interface ItemInternal extends Item {
42
- _id: number
43
- }
44
-
45
- export interface ItemsPerPageSelect {
46
- external?: boolean
47
- label?: string
48
- values?: Array<number>
49
- }
50
-
51
- export interface Pagination {
52
- external?: boolean
53
- }
54
-
55
- export interface Sorter {
56
- resetable?: boolean
57
- external?: boolean
58
- }
59
-
60
- export interface ScopedColumns {
61
- [key: string]: any
62
- details?: (a: Item, b: number) => ReactNode
63
- }
64
-
65
- export interface SorterValue {
66
- column?: string
67
- state?: number | string
68
- }
69
-
70
- export interface TableFilter {
71
- lazy?: boolean
72
- external?: boolean
73
- }
74
-
75
- export interface NoItemsView {
76
- noResults?: string
77
- noItems?: string
78
- }
9
+ import type {
10
+ Column,
11
+ ColumnFilter,
12
+ ColumnFilterValue,
13
+ FooterItem,
14
+ Item,
15
+ ItemsPerPageSelect,
16
+ Pagination,
17
+ Sorter,
18
+ ScopedColumns,
19
+ SorterValue,
20
+ TableFilter,
21
+ } from './types'
79
22
 
80
23
  export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
81
24
  /**
@@ -125,6 +68,12 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
125
68
  * - resetable (Boolean) - If set to true clicking on sorter have three states: ascending, descending and null. That means that third click on sorter will reset sorting, and restore table to original order.
126
69
  */
127
70
  columnSorter?: boolean | Sorter
71
+ /**
72
+ * ReactNode for passing custom CElementCover content.
73
+ *
74
+ * @since 4.9.0
75
+ */
76
+ elementCover?: ReactNode
128
77
  /**
129
78
  * If `true` Displays table footer, which mirrors table header. (without column filter).
130
79
  * Or Array of objects or strings, where each element represents one cell in the table footer.
@@ -144,8 +93,14 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
144
93
  *
145
94
  * Example item:
146
95
  * `{ name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}`
96
+ *
97
+ * @since 4.9.0
147
98
  */
148
99
  items?: Item[]
100
+ /**
101
+ * The total number of items. Use if you pass a portion of data from an external source to let know component what is the total number of items.
102
+ */
103
+ itemsNumber?: number
149
104
  /**
150
105
  * Number of items per site, when pagination is enabled.
151
106
  */
@@ -193,6 +148,12 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
193
148
  * Row click callback.
194
149
  */
195
150
  onRowClick?: (item: Item, index: number, columnName: string, event: MouseEvent | boolean) => void
151
+ /**
152
+ * Select all callback.
153
+ *
154
+ * @since 4.9.0
155
+ */
156
+ onSelectAll?: () => void
196
157
  /**
197
158
  * Selected items change callback.
198
159
  */
@@ -221,6 +182,23 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
221
182
  * Add checkboxes to make table rows selectable.
222
183
  */
223
184
  selectable?: boolean
185
+ /**
186
+ * Enables select all checkbox displayed in the header of the table.
187
+ *
188
+ * Can be customized, by passing prop as object with additional options as keys. Available options:
189
+ * - external (Boolean) - Disables automatic selection inside the component.
190
+ *
191
+ * @since 4.9.0
192
+ */
193
+ selectAll?: boolean | { external?: boolean }
194
+ /**
195
+ * Array of selected objects, where each object represents one item - row in table.
196
+ *
197
+ * Example item: `{ name: 'John' , age: 12 }`
198
+ *
199
+ * @since 4.9.0
200
+ */
201
+ selected?: Item[]
224
202
  /**
225
203
  * State of the sorter. Name key is column name, direction can be 'asc' or 'desc'.
226
204
  */
@@ -1,8 +1,7 @@
1
1
  import React, { forwardRef, HTMLAttributes } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
 
4
- import { CFormLabel } from '../form/CFormLabel'
5
- import { CFormSelect } from '../form/CFormSelect'
4
+ import { CFormLabel, CFormSelect } from '../form/'
6
5
 
7
6
  interface CSmartTableItemsPerPageSelectorProps extends HTMLAttributes<HTMLSelectElement> {
8
7
  itemsPerPage?: number
@@ -0,0 +1,65 @@
1
+ import { ReactNode } from 'react'
2
+
3
+ import { CTableDataCellProps } from '../table/CTableDataCell'
4
+ import { CTableHeaderCellProps } from '../table/CTableHeaderCell'
5
+ import { CTableRowProps } from '../table/CTableRow'
6
+
7
+ export type Column = {
8
+ filter?: boolean | ((values: any[], onChange: (value: any) => void) => ReactNode)
9
+ key: string
10
+ label?: string
11
+ sorter?: boolean
12
+ _style?: any
13
+ _props?: CTableHeaderCellProps
14
+ }
15
+
16
+ export type ColumnFilter = {
17
+ lazy?: boolean
18
+ external?: boolean
19
+ }
20
+
21
+ export type ColumnFilterValue = {
22
+ [key: string]: any
23
+ }
24
+
25
+ export type FooterItem = {
26
+ label?: string
27
+ _props?: CTableDataCellProps
28
+ }
29
+
30
+ export type Item = {
31
+ [key: string]: number | string | any
32
+ _cellProps?: any
33
+ _props?: CTableRowProps
34
+ _selected?: boolean
35
+ }
36
+
37
+ export type ItemsPerPageSelect = {
38
+ external?: boolean
39
+ label?: string
40
+ values?: Array<number>
41
+ }
42
+
43
+ export type Pagination = {
44
+ external?: boolean
45
+ }
46
+
47
+ export type Sorter = {
48
+ resetable?: boolean
49
+ external?: boolean
50
+ }
51
+
52
+ export type ScopedColumns = {
53
+ [key: string]: any
54
+ details?: (a: Item, b: number) => ReactNode
55
+ }
56
+
57
+ export type SorterValue = {
58
+ column?: string
59
+ state?: number | string
60
+ }
61
+
62
+ export type TableFilter = {
63
+ lazy?: boolean
64
+ external?: boolean
65
+ }
@@ -0,0 +1,199 @@
1
+ import type {
2
+ Column,
3
+ ColumnFilter,
4
+ ColumnFilterValue,
5
+ Item,
6
+ Sorter,
7
+ SorterValue,
8
+ TableFilter,
9
+ } from './types'
10
+
11
+ export const filterColumns = (
12
+ items: Item[],
13
+ columnFilter: boolean | ColumnFilter | undefined,
14
+ columnFilterState: ColumnFilterValue,
15
+ itemsDataColumns: string[],
16
+ ) => {
17
+ if (columnFilter && typeof columnFilter === 'object' && columnFilter.external) {
18
+ return items
19
+ }
20
+
21
+ Object.entries(columnFilterState).forEach(([key, value]) => {
22
+ if (value instanceof Function) {
23
+ items = items.filter((item) => value(item[key]))
24
+ return
25
+ }
26
+
27
+ const columnFilter = String(value).toLowerCase()
28
+ if (columnFilter && itemsDataColumns.includes(key)) {
29
+ items = items.filter((item) => {
30
+ return String(item[key]).toLowerCase().includes(columnFilter)
31
+ })
32
+ }
33
+ })
34
+
35
+ return items
36
+ }
37
+
38
+ export const filterTable = (
39
+ items: Item[],
40
+ tableFilter: boolean | TableFilter | undefined,
41
+ tableFilterState: string,
42
+ itemsDataColumns: string[],
43
+ ) => {
44
+ if (
45
+ !tableFilterState ||
46
+ (tableFilter && typeof tableFilter === 'object' && tableFilter.external)
47
+ ) {
48
+ return items
49
+ }
50
+
51
+ const filter = tableFilterState.toLowerCase()
52
+ const valueContainFilter = (val: any) => String(val).toLowerCase().includes(filter)
53
+ items = items.filter((item) => {
54
+ return !!itemsDataColumns.find((key) => valueContainFilter(item[key]))
55
+ })
56
+
57
+ return items
58
+ }
59
+
60
+ export const getClickedColumnName = (
61
+ target: HTMLTextAreaElement,
62
+ columnNames: string[],
63
+ ): string => {
64
+ const closest = target.closest('tr')
65
+ const children = closest ? Array.from(closest.children) : []
66
+ const clickedCell = children.filter((child) => child.contains(target))[0]
67
+ return columnNames[children.indexOf(clickedCell)]
68
+ }
69
+
70
+ export const getColumnKey = (column: Column | string) =>
71
+ typeof column === 'object' ? column.key : column
72
+
73
+ export const getColumnLabel = (column: Column | string) =>
74
+ typeof column === 'object'
75
+ ? column.label !== undefined
76
+ ? column.label
77
+ : pretifyName(column.key)
78
+ : pretifyName(column)
79
+
80
+ export const getColumnNames = (columns: (string | Column)[] | undefined, items: Item[]) =>
81
+ columns
82
+ ? columns.map((column: Column | string) => {
83
+ if (typeof column === 'object') return column.key
84
+ else return column
85
+ })
86
+ : getColumnNamesFromItems(items)
87
+
88
+ export const getColumnNamesFromItems = (items: Item[]) =>
89
+ Object.keys(items[0] || {}).filter((el) => el.charAt(0) !== '_')
90
+
91
+ export const getColumnSorterState = (
92
+ key: string,
93
+ sorterState: SorterValue | undefined,
94
+ ): string | number => {
95
+ if (sorterState && sorterState.column === key) {
96
+ if (sorterState.state) {
97
+ return sorterState.state
98
+ }
99
+ return 0
100
+ }
101
+
102
+ return 0
103
+ }
104
+
105
+ export const getColumnValues = (items: Item[], key: string) => {
106
+ return items.map((item) => item[key])
107
+ }
108
+
109
+ export const getTableDataCellProps = (item: Item, colName: string) => {
110
+ const props = item._cellProps && {
111
+ ...(item._cellProps['all'] && { ...item._cellProps['all'] }),
112
+ ...(item._cellProps[colName] && { ...item._cellProps[colName] }),
113
+ }
114
+
115
+ return props
116
+ }
117
+
118
+ export const getTableHeaderCellProps = (column: Column | string) => {
119
+ if (typeof column === 'object' && column._props) {
120
+ return column._props
121
+ }
122
+
123
+ return {}
124
+ }
125
+
126
+ export const getTableHeaderCellStyles = (
127
+ column: Column | string,
128
+ columnSorter: boolean | Sorter | undefined,
129
+ ) => {
130
+ const style = {}
131
+
132
+ if (
133
+ columnSorter &&
134
+ (typeof column !== 'object' ||
135
+ (typeof column === 'object' && (typeof column.sorter === 'undefined' || column.sorter)))
136
+ ) {
137
+ style['cursor'] = 'pointer'
138
+ }
139
+
140
+ if (typeof column === 'object' && column._style) {
141
+ return { ...style, ...column._style }
142
+ }
143
+ return style
144
+ }
145
+
146
+ export const isSortable = (
147
+ i: number,
148
+ columns: (string | Column)[] | undefined,
149
+ columnSorter: Sorter | boolean | undefined,
150
+ itemsDataColumns: string[],
151
+ columnNames: string[],
152
+ ): boolean | undefined => {
153
+ const isDataColumn = itemsDataColumns.includes(columnNames[i])
154
+ let column
155
+ if (columns) column = columns[i]
156
+ return (
157
+ columnSorter &&
158
+ (!columns ||
159
+ typeof column !== 'object' ||
160
+ (typeof column === 'object' && (typeof column.sorter === 'undefined' || column.sorter))) &&
161
+ isDataColumn
162
+ )
163
+ }
164
+
165
+ export const pretifyName = (name: string) => {
166
+ return name
167
+ .replace(/[-_.]/g, ' ')
168
+ .replace(/ +/g, ' ')
169
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
170
+ .split(' ')
171
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
172
+ .join(' ')
173
+ }
174
+
175
+ export const sortItems = (
176
+ columnSorter: boolean | Sorter | undefined,
177
+ items: Item[],
178
+ itemsDataColumns: string[],
179
+ sorterState: SorterValue,
180
+ ) => {
181
+ const column = sorterState.column
182
+ if (
183
+ !column ||
184
+ !itemsDataColumns.includes(column) ||
185
+ (columnSorter && typeof columnSorter === 'object' && columnSorter.external)
186
+ ) {
187
+ return items
188
+ }
189
+
190
+ const flip = sorterState.state === 'asc' ? 1 : sorterState.state === 'desc' ? -1 : 0
191
+ const sorted = items.slice().sort((item, item2) => {
192
+ const value = item[column]
193
+ const value2 = item2[column]
194
+ const a = typeof value === 'number' ? value : String(value).toLowerCase()
195
+ const b = typeof value2 === 'number' ? value2 : String(value2).toLowerCase()
196
+ return a > b ? 1 * flip : b > a ? -1 * flip : 0
197
+ })
198
+ return sorted
199
+ }
@@ -2,7 +2,8 @@ import React, { ElementType, forwardRef, HTMLAttributes } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
- import { Colors, colorPropType } from '../Types'
5
+ import { colorPropType } from '../../props'
6
+ import type { Colors } from '../../types'
6
7
 
7
8
  export interface CSpinnerProps extends HTMLAttributes<HTMLDivElement | HTMLSpanElement> {
8
9
  /**
@@ -1,17 +1,21 @@
1
- import React, { forwardRef, TableHTMLAttributes } from 'react'
1
+ import React, { forwardRef, TableHTMLAttributes, useMemo } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
- import { Colors, colorPropType } from '../Types'
6
5
  import { CTableHead, CTableHeadProps } from './CTableHead'
7
- import { CTableHeaderCell, CTableHeaderCellProps } from './CTableHeaderCell'
6
+ import { CTableHeaderCell } from './CTableHeaderCell'
8
7
  import { CTableBody } from './CTableBody'
9
- import { CTableDataCell, CTableDataCellProps } from './CTableDataCell'
10
- import { CTableRow, CTableRowProps } from './CTableRow'
8
+ import { CTableDataCell } from './CTableDataCell'
9
+ import { CTableRow } from './CTableRow'
11
10
  import { CTableFoot, CTableFootProps } from './CTableFoot'
12
11
  import { CTableCaption } from './CTableCaption'
13
12
  import { CTableResponsiveWrapper } from './CTableResponsiveWrapper'
14
13
 
14
+ import { colorPropType } from '../../props'
15
+ import type { Colors } from '../../types'
16
+ import { getColumnLabel, getColumnNames } from './utils'
17
+ import type { Column, FooterItem, Item } from './types'
18
+
15
19
  export interface CTableProps extends Omit<TableHTMLAttributes<HTMLTableElement>, 'align'> {
16
20
  /**
17
21
  * Set the vertical aligment.
@@ -123,23 +127,6 @@ export interface CTableProps extends Omit<TableHTMLAttributes<HTMLTableElement>,
123
127
  tableHeadProps?: CTableHeadProps
124
128
  }
125
129
 
126
- export interface Column {
127
- label?: string
128
- key: string
129
- _style?: any
130
- _props?: CTableHeaderCellProps
131
- }
132
-
133
- export interface Item {
134
- [key: string]: number | string | any
135
- _props?: CTableRowProps
136
- }
137
-
138
- export interface FooterItem {
139
- label?: string
140
- _props?: CTableDataCellProps
141
- }
142
-
143
130
  export const CTable = forwardRef<HTMLTableElement, CTableProps>(
144
131
  (
145
132
  {
@@ -183,29 +170,7 @@ export const CTable = forwardRef<HTMLTableElement, CTableProps>(
183
170
  className,
184
171
  )
185
172
 
186
- const rawColumnNames = columns
187
- ? columns.map((column: Column) => {
188
- if (typeof column === 'object') return column.key
189
- else return column
190
- })
191
- : Object.keys((items && items[0]) || {}).filter((el) => el.charAt(0) !== '_')
192
-
193
- const pretifyName = (name: string) => {
194
- return name
195
- .replace(/[-_.]/g, ' ')
196
- .replace(/ +/g, ' ')
197
- .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
198
- .split(' ')
199
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
200
- .join(' ')
201
- }
202
-
203
- const label = (column: Column | string) =>
204
- typeof column === 'object'
205
- ? column.label !== undefined
206
- ? column.label
207
- : pretifyName(column.key)
208
- : pretifyName(column)
173
+ const columnNames = useMemo(() => getColumnNames(columns, items), [columns, items])
209
174
 
210
175
  return (
211
176
  <CTableResponsiveWrapper responsive={responsive}>
@@ -222,7 +187,7 @@ export const CTable = forwardRef<HTMLTableElement, CTableProps>(
222
187
  {...(column._style && { style: { ...column._style } })}
223
188
  key={index}
224
189
  >
225
- {label(column)}
190
+ {getColumnLabel(column)}
226
191
  </CTableHeaderCell>
227
192
  ))}
228
193
  </CTableRow>
@@ -232,19 +197,20 @@ export const CTable = forwardRef<HTMLTableElement, CTableProps>(
232
197
  <CTableBody>
233
198
  {items.map((item: Item, index: number) => (
234
199
  <CTableRow {...(item._props && { ...item._props })} key={index}>
235
- {rawColumnNames.map((colName: string, index: number) => {
236
- return item[colName] ? (
237
- <CTableDataCell
238
- {...(item._cellProps && {
239
- ...(item._cellProps['all'] && { ...item._cellProps['all'] }),
240
- ...(item._cellProps[colName] && { ...item._cellProps[colName] }),
241
- })}
242
- key={index}
243
- >
244
- {item[colName]}
245
- </CTableDataCell>
246
- ) : null
247
- })}
200
+ {columnNames &&
201
+ columnNames.map((colName: string, index: number) => {
202
+ return item[colName] ? (
203
+ <CTableDataCell
204
+ {...(item._cellProps && {
205
+ ...(item._cellProps['all'] && { ...item._cellProps['all'] }),
206
+ ...(item._cellProps[colName] && { ...item._cellProps[colName] }),
207
+ })}
208
+ key={index}
209
+ >
210
+ {item[colName]}
211
+ </CTableDataCell>
212
+ ) : null
213
+ })}
248
214
  </CTableRow>
249
215
  ))}
250
216
  </CTableBody>
@@ -2,7 +2,8 @@ import React, { forwardRef, HTMLAttributes } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
- import { Colors, colorPropType } from '../Types'
5
+ import { colorPropType } from '../../props'
6
+ import type { Colors } from '../../types'
6
7
 
7
8
  export interface CTableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {
8
9
  /**
@@ -2,7 +2,8 @@ import React, { forwardRef, TdHTMLAttributes, ThHTMLAttributes } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
- import { Colors, colorPropType } from '../Types'
5
+ import { colorPropType } from '../../props'
6
+ import type { Colors } from '../../types'
6
7
 
7
8
  export interface CTableDataCellProps
8
9
  extends Omit<TdHTMLAttributes<HTMLTableCellElement>, 'align'>,
@@ -2,7 +2,8 @@ import PropTypes from 'prop-types'
2
2
  import React, { forwardRef, HTMLAttributes } from 'react'
3
3
  import classNames from 'classnames'
4
4
 
5
- import { Colors, colorPropType } from '../Types'
5
+ import { colorPropType } from '../../props'
6
+ import type { Colors } from '../../types'
6
7
 
7
8
  export interface CTableFootProps extends HTMLAttributes<HTMLTableSectionElement> {
8
9
  /**
@@ -2,7 +2,8 @@ import React, { forwardRef, HTMLAttributes } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
- import { Colors, colorPropType } from '../Types'
5
+ import { colorPropType } from '../../props'
6
+ import type { Colors } from '../../types'
6
7
 
7
8
  export interface CTableHeadProps extends HTMLAttributes<HTMLTableSectionElement> {
8
9
  /**
@@ -2,7 +2,8 @@ import React, { forwardRef, ThHTMLAttributes } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
- import { Colors, colorPropType } from '../Types'
5
+ import { colorPropType } from '../../props'
6
+ import type { Colors } from '../../types'
6
7
 
7
8
  export interface CTableHeaderCellProps extends ThHTMLAttributes<HTMLTableCellElement> {
8
9
  /**
@@ -2,7 +2,8 @@ import React, { forwardRef, HTMLAttributes } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
- import { Colors, colorPropType } from '../Types'
5
+ import { colorPropType } from '../../props'
6
+ import type { Colors } from '../../types'
6
7
 
7
8
  export interface CTableRowProps extends HTMLAttributes<HTMLTableRowElement> {
8
9
  /**
@@ -0,0 +1,20 @@
1
+ import { CTableDataCellProps } from '../table/CTableDataCell'
2
+ import { CTableHeaderCellProps } from '../table/CTableHeaderCell'
3
+ import { CTableRowProps } from '../table/CTableRow'
4
+
5
+ export type Column = {
6
+ label?: string
7
+ key: string
8
+ _style?: any
9
+ _props?: CTableHeaderCellProps
10
+ }
11
+
12
+ export type FooterItem = {
13
+ label?: string
14
+ _props?: CTableDataCellProps
15
+ }
16
+
17
+ export type Item = {
18
+ [key: string]: number | string | any
19
+ _props?: CTableRowProps
20
+ }
@@ -0,0 +1,29 @@
1
+ import type { Column, Item } from './types'
2
+
3
+ export const pretifyName = (name: string) => {
4
+ return name
5
+ .replace(/[-_.]/g, ' ')
6
+ .replace(/ +/g, ' ')
7
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
8
+ .split(' ')
9
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
10
+ .join(' ')
11
+ }
12
+
13
+ export const getColumnLabel = (column: Column | string) =>
14
+ typeof column === 'object'
15
+ ? column.label !== undefined
16
+ ? column.label
17
+ : pretifyName(column.key)
18
+ : pretifyName(column)
19
+
20
+ export const getColumnNames = (columns: (string | Column)[] | undefined, items?: Item[]) =>
21
+ columns
22
+ ? columns.map((column: Column | string) => {
23
+ if (typeof column === 'object') return column.key
24
+ else return column
25
+ })
26
+ : items && getColumnNamesFromItems(items)
27
+
28
+ export const getColumnNamesFromItems = (items: Item[]) =>
29
+ Object.keys(items[0] || {}).filter((el) => el.charAt(0) !== '_')