@coreui/react-pro 4.8.0-alpha.3 → 4.9.0-next.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 (82) hide show
  1. package/README.md +1 -1
  2. package/dist/components/calendar/index.d.ts +2 -0
  3. package/dist/components/calendar/utils.d.ts +23 -0
  4. package/dist/components/date-picker/CDatePicker.d.ts +1 -1
  5. package/dist/components/date-range-picker/CDateRangePicker.d.ts +2 -2
  6. package/dist/components/element-cover/CElementCover.d.ts +3 -7
  7. package/dist/components/element-cover/index.d.ts +2 -0
  8. package/dist/components/form/CFormInput.d.ts +1 -1
  9. package/dist/components/form/CFormSwitch.d.ts +1 -1
  10. package/dist/components/index.d.ts +2 -0
  11. package/dist/components/nav/CNavGroup.d.ts +4 -4
  12. package/dist/components/offcanvas/COffcanvas.d.ts +8 -2
  13. package/dist/components/sidebar/CSidebar.d.ts +4 -4
  14. package/dist/components/smart-table/CSmartTableBody.d.ts +6 -5
  15. package/dist/components/smart-table/CSmartTableHead.d.ts +6 -3
  16. package/dist/components/smart-table/CSmartTableInterface.d.ts +46 -109
  17. package/dist/components/smart-table/types.d.ts +53 -0
  18. package/dist/components/smart-table/utils.d.ts +16 -0
  19. package/dist/components/table/CTable.d.ts +5 -5
  20. package/dist/components/time-picker/types.d.ts +15 -0
  21. package/dist/components/time-picker/utils.d.ts +23 -0
  22. package/dist/hooks/index.d.ts +3 -0
  23. package/dist/hooks/useForkedRef.d.ts +7 -0
  24. package/dist/hooks/useStateWithCallback.d.ts +2 -0
  25. package/dist/index.es.js +1246 -1865
  26. package/dist/index.es.js.map +1 -1
  27. package/dist/index.js +1246 -1863
  28. package/dist/index.js.map +1 -1
  29. package/dist/utils/index.d.ts +3 -2
  30. package/dist/utils/isInViewport.d.ts +2 -0
  31. package/dist/utils/isObjectInArray.d.ts +2 -0
  32. package/package.json +14 -14
  33. package/src/components/accordion/CAccordionBody.tsx +1 -1
  34. package/src/components/alert/CAlert.tsx +1 -1
  35. package/src/components/backdrop/CBackdrop.tsx +1 -1
  36. package/src/components/calendar/CCalendar.tsx +351 -240
  37. package/src/components/calendar/index.ts +3 -0
  38. package/src/{utils/calendar.ts → components/calendar/utils.ts} +1 -1
  39. package/src/components/carousel/CCarousel.tsx +4 -4
  40. package/src/components/carousel/CCarouselItem.tsx +1 -1
  41. package/src/components/collapse/CCollapse.tsx +1 -1
  42. package/src/components/date-picker/CDatePicker.tsx +1 -1
  43. package/src/components/date-range-picker/CDateRangePicker.tsx +3 -3
  44. package/src/components/dropdown/CDropdown.tsx +1 -1
  45. package/src/components/dropdown/CDropdownToggle.tsx +1 -1
  46. package/src/components/element-cover/CElementCover.tsx +19 -25
  47. package/src/components/element-cover/index.ts +3 -0
  48. package/src/components/form/CFormCheck.tsx +1 -1
  49. package/src/components/form/CFormControlWrapper.tsx +14 -20
  50. package/src/components/form/CFormInput.tsx +1 -1
  51. package/src/components/form/CFormSwitch.tsx +1 -1
  52. package/src/components/grid/CCol.tsx +4 -0
  53. package/src/components/index.ts +2 -0
  54. package/src/components/modal/CModal.tsx +1 -1
  55. package/src/components/nav/CNavGroup.tsx +4 -4
  56. package/src/components/nav/CNavLink.tsx +2 -1
  57. package/src/components/offcanvas/COffcanvas.tsx +36 -18
  58. package/src/components/sidebar/CSidebar.tsx +10 -10
  59. package/src/components/smart-table/CSmartTable.tsx +279 -259
  60. package/src/components/smart-table/CSmartTableBody.tsx +31 -41
  61. package/src/components/smart-table/CSmartTableCleaner.tsx +1 -1
  62. package/src/components/smart-table/CSmartTableFilter.tsx +1 -3
  63. package/src/components/smart-table/CSmartTableHead.tsx +53 -103
  64. package/src/components/smart-table/CSmartTableInterface.tsx +57 -120
  65. package/src/components/smart-table/CSmartTableItemsPerPageSelector.tsx +1 -2
  66. package/src/components/smart-table/types.tsx +65 -0
  67. package/src/components/smart-table/utils.tsx +199 -0
  68. package/src/components/table/CTable.tsx +12 -9
  69. package/src/components/tabs/CTabPane.tsx +1 -1
  70. package/src/components/time-picker/CTimePicker.tsx +50 -23
  71. package/src/components/time-picker/CTimePickerRollCol.tsx +1 -1
  72. package/src/components/time-picker/types.ts +15 -0
  73. package/src/{utils/time.ts → components/time-picker/utils.ts} +43 -2
  74. package/src/components/toast/CToast.tsx +1 -1
  75. package/src/components/virtual-scroller/CVirtualScroller.tsx +1 -1
  76. package/src/{utils/hooks → hooks}/index.ts +0 -0
  77. package/src/{utils/hooks → hooks}/useForkedRef.ts +0 -0
  78. package/src/{utils/hooks → hooks}/useStateWithCallback.ts +0 -0
  79. package/src/utils/index.ts +3 -2
  80. package/src/utils/isInViewport.ts +11 -0
  81. package/src/utils/isObjectInArray.ts +14 -0
  82. package/src/utils/isVisible.ts +0 -11
@@ -1,81 +1,28 @@
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
5
  import { CTableBodyProps } from '../table/CTableBody'
5
6
  import { CTableFootProps } from '../table/CTableFoot'
6
- import { CTableHeaderCellProps } from '../table/CTableHeaderCell'
7
- import { CTableRowProps } from '../table/CTableRow'
8
7
  import { CTableHeadProps } from '../table/CTableHead'
9
8
 
10
- export interface Column {
11
- filter?: boolean | ((values: any[], onChange: (value: any) => void) => ReactNode)
12
- label?: string
13
- key: string
14
- sorter?: boolean
15
- _style?: any
16
- _props?: CTableHeaderCellProps
17
- }
18
-
19
- export interface ColumnFilter {
20
- lazy?: boolean
21
- external?: boolean
22
- }
23
-
24
- export interface ColumnFilterValue {
25
- [key: string]: any
26
- }
27
-
28
- export interface Item {
29
- [key: string]: number | string | any
30
- _cellProps?: any
31
- _props?: CTableRowProps
32
- _selected?: boolean
33
- }
34
-
35
- export interface ItemInternal extends Item {
36
- _id: number
37
- }
38
-
39
- export interface ItemsPerPageSelect {
40
- external?: boolean
41
- label?: string
42
- values?: Array<number>
43
- }
44
-
45
- export interface Pagination {
46
- external?: boolean
47
- }
48
-
49
- export interface Sorter {
50
- resetable?: boolean
51
- external?: boolean
52
- }
53
-
54
- export interface ScopedColumns {
55
- [key: string]: any
56
- details?: (a: Item, b: number) => ReactNode
57
- }
58
-
59
- export interface SorterValue {
60
- column?: string
61
- state?: number | string
62
- }
63
-
64
- export interface TableFilter {
65
- lazy?: boolean
66
- external?: boolean
67
- }
68
-
69
- export interface NoItemsView {
70
- noResults?: string
71
- noItems?: string
72
- }
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'
73
22
 
74
23
  export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
75
24
  /**
76
25
  * Sets active page. If 'pagination' prop is enabled, activePage is set only initially.
77
- *
78
- * @default 1
79
26
  */
80
27
  activePage?: number
81
28
  /**
@@ -85,8 +32,6 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
85
32
  cleaner?: boolean
86
33
  /**
87
34
  * Style table items as clickable.
88
- *
89
- * @type boolean
90
35
  */
91
36
  clickableRows?: boolean
92
37
  /**
@@ -94,13 +39,11 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
94
39
  * Column filter can be customized, by passing prop as object with additional options as keys. Available options:
95
40
  * - external (Boolean) - Disables automatic filtering inside component.
96
41
  * - lazy (Boolean) - Set to true to trigger filter updates only on change event.
97
- *
98
- * @type boolean | ColumnFilter
99
42
  */
100
43
  columnFilter?: boolean | ColumnFilter
101
44
  /**
102
45
  * Value of table filter. To set pass object where keys are column names and values are filter strings e.g.:
103
- * { user: 'John', age: 12 }
46
+ * `{ user: 'John', age: 12 }`
104
47
  */
105
48
  columnFilterValue?: ColumnFilterValue
106
49
  /**
@@ -123,46 +66,49 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
123
66
  * Sorter can be customized, by passing prop as object with additional options as keys. Available options:
124
67
  * - external (Boolean) - Disables automatic sorting inside component.
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
- *
127
- * @type boolean | Sorter
128
69
  */
129
70
  columnSorter?: boolean | Sorter
130
71
  /**
131
- * Displays table footer, which mirrors table header. (without column filter).
72
+ * ReactNode for passing custom CElementCover content.
73
+ *
74
+ * @since 4.9.0
132
75
  */
133
- footer?: boolean
76
+ elementCover?: ReactNode
134
77
  /**
135
- * Set to false to remove table header.
78
+ * If `true` Displays table footer, which mirrors table header. (without column filter).
79
+ * Or Array of objects or strings, where each element represents one cell in the table footer.
136
80
  *
137
- * @default true
81
+ * Example items:
82
+ * `['FooterCell', 'FooterCell', 'FooterCell']`
83
+ * or
84
+ * `[{ label: 'FooterCell', _props: { color: 'success' }, ...]`
85
+ */
86
+ footer?: boolean | (FooterItem | string)[]
87
+ /**
88
+ * Set to false to remove table header.
138
89
  */
139
90
  header?: boolean
140
91
  /**
141
- * Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '_classes' key and to single cell by '_cellClasses'.
92
+ * Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '_props' key and to single cell by '_cellProps'.
142
93
  *
143
94
  * Example item:
144
- * { name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}
145
- * For column generation description watch columns prop.
146
- *
147
- * @type Array<string>
95
+ * `{ name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}`
148
96
  */
149
97
  items?: Item[]
98
+ /**
99
+ * 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.
100
+ */
101
+ itemsNumber?: number
150
102
  /**
151
103
  * Number of items per site, when pagination is enabled.
152
- *
153
- * @default 10
154
104
  */
155
105
  itemsPerPage?: number
156
106
  /**
157
107
  * Label for items per page selector.
158
- *
159
- * @default 'Items per page:'
160
108
  */
161
109
  itemsPerPageLabel?: string
162
110
  /**
163
111
  * Items per page selector options.
164
- *
165
- * @default [5, 10, 20, 50]
166
112
  */
167
113
  itemsPerPageOptions?: number[]
168
114
  /**
@@ -178,7 +124,6 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
178
124
  loading?: boolean
179
125
  /**
180
126
  * ReactNode or string for passing custom noItemsLabel texts.
181
- * @default 'No items found'
182
127
  */
183
128
  noItemsLabel?: string | ReactNode
184
129
  /**
@@ -201,6 +146,10 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
201
146
  * Row click callback.
202
147
  */
203
148
  onRowClick?: (item: Item, index: number, columnName: string, event: MouseEvent | boolean) => void
149
+ /**
150
+ * Select all callback.
151
+ */
152
+ onSelectAll?: () => void
204
153
  /**
205
154
  * Selected items change callback.
206
155
  */
@@ -218,15 +167,11 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
218
167
  */
219
168
  pagination?: boolean | Pagination
220
169
  /**
221
- * Properties to `CSmartPagination` component.
222
- *
223
- * @link https://coreui.io/react/docs/components/smart-pagination#csmartpagination
170
+ * Properties to `CSmartPagination` component - https://coreui.io/react/docs/components/smart-pagination#csmartpagination
224
171
  */
225
172
  paginationProps?: CSmartPaginationProps
226
173
  /**
227
174
  * Scoped columns.
228
- *
229
- * @type scopedColumns
230
175
  */
231
176
  scopedColumns?: ScopedColumns
232
177
  /**
@@ -234,39 +179,40 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
234
179
  */
235
180
  selectable?: boolean
236
181
  /**
237
- * State of the sorter. Name key is column name, direction can be 'asc' or 'desc'.
182
+ * Enables select all checkbox displayed in the header of the table.
183
+ *
184
+ * Can be customized, by passing prop as object with additional options as keys. Available options:
185
+ * - external (Boolean) - Disables automatic selection inside the component.
186
+ */
187
+ selectAll?: boolean | { external?: boolean }
188
+ /**
189
+ * Array of selected objects, where each object represents one item - row in table.
238
190
  *
239
- * @type SorterValue
191
+ * Example item: `{ name: 'John' , age: 12 }`
192
+ */
193
+ selected?: Item[]
194
+ /**
195
+ * State of the sorter. Name key is column name, direction can be 'asc' or 'desc'.
240
196
  */
241
197
  sorterValue?: SorterValue
242
198
  /**
243
199
  * Sorter icon when items are unsorted.
244
- *
245
- * @default '<CIcon width="18" content={cilArrowTop} />
246
200
  */
247
201
  sortingIcon?: ReactNode
248
202
  /**
249
203
  * Sorter icon when items are sorted ascending.
250
- *
251
- * @default '<CIcon width="18" content={cilArrowTop} />
252
204
  */
253
205
  sortingIconAscending?: ReactNode
254
206
  /**
255
207
  * Sorter icon when items are sorted descending.
256
- *
257
- * @default '<CIcon width="18" content={cilArrowBottom} />'
258
208
  */
259
209
  sortingIconDescending?: ReactNode
260
210
  /**
261
- * Properties to `CTableBody` component.
262
- *
263
- * @link https://coreui.io/react/docs/components/table/#ctablebody
211
+ * Properties to `CTableBody` component - https://coreui.io/react/docs/components/table/#ctablebody
264
212
  */
265
213
  tableBodyProps?: CTableBodyProps
266
214
  /**
267
- * Properties to `CTableFoot` component.
268
- *
269
- * @link https://coreui.io/react/docs/components/table/#ctablefoot
215
+ * Properties to `CTableFoot` component - https://coreui.io/react/docs/components/table/#ctablefoot
270
216
  */
271
217
  tableFootProps?: CTableFootProps
272
218
  /**
@@ -279,31 +225,22 @@ export interface CSmartTableProps extends HTMLAttributes<HTMLDivElement> {
279
225
  tableFilter?: boolean | TableFilter
280
226
  /**
281
227
  * The element represents a caption for a component.
282
- *
283
- * @default 'Filter:'
284
228
  */
285
229
  tableFilterLabel?: string
286
230
  /**
287
231
  * Specifies a short hint that is visible in the search input.
288
- *
289
- * @default 'type string...'
290
232
  */
291
233
  tableFilterPlaceholder?: string
292
234
  /**
293
235
  * Value of table filter.
294
- *
295
236
  */
296
237
  tableFilterValue?: string
297
238
  /**
298
- * Properties to `CTableHead` component.
299
- *
300
- * @link https://coreui.io/react/docs/components/table/#ctablehead
239
+ * Properties to `CTableHead` component - https://coreui.io/react/docs/components/table/#ctablehead
301
240
  */
302
241
  tableHeadProps?: CTableHeadProps
303
242
  /**
304
- * Properties to `CTable` component.
305
- *
306
- * @link https://coreui.io/react/docs/components/table/#ctable
243
+ * Properties to `CTable` component - https://coreui.io/react/docs/components/table/#ctable
307
244
  */
308
245
  tableProps?: CTableProps
309
246
  }
@@ -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
+ label?: string
10
+ key: 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) => {
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
+ }
@@ -53,7 +53,7 @@ export interface CTableProps extends Omit<TableHTMLAttributes<HTMLTableElement>,
53
53
  * Object: item is object with following keys available as column configuration:
54
54
  * - key (required)(String) - define column name equal to item key.
55
55
  * - label (String) - define visible label of column. If not defined, label will be generated automatically based on column name, by converting kebab-case and snake_case to individual words and capitalization of each word.
56
- * - _props (Object) - adds classes to all cels in column, ex. _props: { scope: 'col', className: 'custom-class' },
56
+ * - _props (Object) - adds classes to all cels in column, ex. `_props: { scope: 'col', className: 'custom-class' }`,
57
57
  * - _style (Object) - adds styles to the column header (useful for defining widths)
58
58
  *
59
59
  * @since 4.3.0
@@ -69,13 +69,13 @@ export interface CTableProps extends Omit<TableHTMLAttributes<HTMLTableElement>,
69
69
  * Array of objects or strings, where each element represents one cell in the table footer.
70
70
  *
71
71
  * Example items:
72
- * ['FooterCell', 'FooterCell', 'FooterCell']
72
+ * `['FooterCell', 'FooterCell', 'FooterCell']`
73
73
  * or
74
- * [{ label: 'FooterCell', _props: { color: 'success' }, ...]
74
+ * `[{ label: 'FooterCell', _props: { color: 'success' }, ...]`
75
75
  *
76
76
  * @since 4.3.0
77
77
  */
78
- footer?: FooterItem[]
78
+ footer?: (FooterItem | string)[]
79
79
  /**
80
80
  * Enable a hover state on table rows within a `<CTableBody>`.
81
81
  */
@@ -84,7 +84,7 @@ export interface CTableProps extends Omit<TableHTMLAttributes<HTMLTableElement>,
84
84
  * Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '_props' key and to single cell by '_cellProps'.
85
85
  *
86
86
  * Example item:
87
- * { name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}
87
+ * `{ name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}`
88
88
  *
89
89
  * @since 4.3.0
90
90
  */
@@ -155,7 +155,7 @@ export const CTable = forwardRef<HTMLTableElement, CTableProps>(
155
155
  columns,
156
156
  footer,
157
157
  hover,
158
- items = [],
158
+ items,
159
159
  responsive,
160
160
  small,
161
161
  striped,
@@ -188,7 +188,7 @@ export const CTable = forwardRef<HTMLTableElement, CTableProps>(
188
188
  if (typeof column === 'object') return column.key
189
189
  else return column
190
190
  })
191
- : Object.keys(items[0] || {}).filter((el) => el.charAt(0) !== '_')
191
+ : Object.keys((items && items[0]) || {}).filter((el) => el.charAt(0) !== '_')
192
192
 
193
193
  const pretifyName = (name: string) => {
194
194
  return name
@@ -253,8 +253,11 @@ export const CTable = forwardRef<HTMLTableElement, CTableProps>(
253
253
  {footer && (
254
254
  <CTableFoot {...tableFootProps}>
255
255
  <CTableRow>
256
- {footer.map((item: FooterItem, index: number) => (
257
- <CTableDataCell {...(item._props && { ...item._props })} key={index}>
256
+ {footer.map((item: FooterItem | string, index: number) => (
257
+ <CTableDataCell
258
+ {...(typeof item === 'object' && item._props && { ...item._props })}
259
+ key={index}
260
+ >
258
261
  {typeof item === 'object' ? item.label : item}
259
262
  </CTableDataCell>
260
263
  ))}
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
  import { Transition } from 'react-transition-group'
5
5
 
6
- import { useForkedRef } from '../../utils/hooks'
6
+ import { useForkedRef } from '../../hooks'
7
7
  export interface CTabPaneProps extends HTMLAttributes<HTMLDivElement> {
8
8
  /**
9
9
  * A string of all className you want applied to the base component.