@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.
- package/README.md +1 -1
- package/dist/components/alert/CAlert.d.ts +1 -1
- package/dist/components/avatar/CAvatar.d.ts +1 -1
- package/dist/components/badge/CBadge.d.ts +1 -1
- package/dist/components/button/CButton.d.ts +1 -1
- package/dist/components/calendar/index.d.ts +2 -0
- package/dist/components/calendar/utils.d.ts +22 -0
- package/dist/components/callout/CCallout.d.ts +1 -1
- package/dist/components/card/CCard.d.ts +1 -1
- package/dist/components/date-picker/CDatePicker.d.ts +1 -1
- package/dist/components/date-range-picker/CDateRangePicker.d.ts +3 -3
- package/dist/components/date-range-picker/utils.d.ts +1 -0
- package/dist/components/dropdown/CDropdown.d.ts +1 -1
- package/dist/components/dropdown/CDropdownToggle.d.ts +1 -1
- package/dist/components/element-cover/CElementCover.d.ts +0 -4
- package/dist/components/element-cover/index.d.ts +2 -0
- package/dist/components/form/CFormCheck.d.ts +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/list-group/CListGroupItem.d.ts +4 -5
- package/dist/components/multi-select/CMultiSelect.d.ts +1 -13
- package/dist/components/multi-select/CMultiSelectNativeSelect.d.ts +1 -1
- package/dist/components/multi-select/CMultiSelectOptions.d.ts +1 -1
- package/dist/components/multi-select/CMultiSelectSelection.d.ts +1 -1
- package/dist/components/multi-select/types.d.ts +14 -0
- package/dist/components/multi-select/utils.d.ts +6 -0
- package/dist/components/navbar/CNavbar.d.ts +1 -1
- package/dist/components/offcanvas/COffcanvas.d.ts +7 -1
- package/dist/components/picker/CPicker.d.ts +1 -1
- package/dist/components/placeholder/CPlaceholder.d.ts +1 -1
- package/dist/components/popover/CPopover.d.ts +1 -1
- package/dist/components/progress/CProgressBar.d.ts +1 -1
- package/dist/components/smart-table/CSmartTableBody.d.ts +6 -5
- package/dist/components/smart-table/CSmartTableHead.d.ts +6 -3
- package/dist/components/smart-table/CSmartTableInterface.d.ts +38 -59
- package/dist/components/smart-table/types.d.ts +53 -0
- package/dist/components/smart-table/utils.d.ts +16 -0
- package/dist/components/spinner/CSpinner.d.ts +1 -1
- package/dist/components/table/CTable.d.ts +2 -18
- package/dist/components/table/CTableBody.d.ts +1 -1
- package/dist/components/table/CTableDataCell.d.ts +1 -1
- package/dist/components/table/CTableFoot.d.ts +1 -1
- package/dist/components/table/CTableHead.d.ts +1 -1
- package/dist/components/table/CTableHeaderCell.d.ts +1 -1
- package/dist/components/table/CTableRow.d.ts +1 -1
- package/dist/components/table/types.d.ts +17 -0
- package/dist/components/table/utils.d.ts +5 -0
- package/dist/components/time-picker/types.d.ts +15 -0
- package/dist/components/time-picker/utils.d.ts +23 -0
- package/dist/components/toast/CToast.d.ts +1 -1
- package/dist/components/toast/CToastClose.d.ts +1 -1
- package/dist/components/tooltip/CTooltip.d.ts +1 -1
- package/dist/components/virtual-scroller/CVirtualScroller.d.ts +0 -8
- package/dist/components/widgets/CWidgetStatsA.d.ts +1 -1
- package/dist/components/widgets/CWidgetStatsB.d.ts +1 -1
- package/dist/components/widgets/CWidgetStatsC.d.ts +1 -1
- package/dist/components/widgets/CWidgetStatsD.d.ts +1 -1
- package/dist/components/widgets/CWidgetStatsF.d.ts +1 -1
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/useForkedRef.d.ts +7 -0
- package/dist/hooks/useStateWithCallback.d.ts +2 -0
- package/dist/index.es.js +1171 -1109
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +1171 -1108
- package/dist/index.js.map +1 -1
- package/dist/props.d.ts +8 -0
- package/dist/types.d.ts +7 -0
- package/dist/utils/index.d.ts +2 -3
- package/dist/utils/isObjectInArray.d.ts +2 -0
- package/package.json +11 -11
- package/src/components/accordion/CAccordionBody.tsx +1 -0
- package/src/components/accordion/CAccordionCollapse.tsx +1 -0
- package/src/components/alert/CAlert.tsx +3 -2
- package/src/components/avatar/CAvatar.tsx +2 -8
- package/src/components/backdrop/CBackdrop.tsx +2 -2
- package/src/components/badge/CBadge.tsx +2 -10
- package/src/components/button/CButton.tsx +3 -1
- package/src/components/calendar/CCalendar.tsx +351 -240
- package/src/components/calendar/index.ts +3 -0
- package/src/{utils/calendar.ts → components/calendar/utils.ts} +1 -47
- package/src/components/callout/CCallout.tsx +2 -1
- package/src/components/card/CCard.tsx +2 -1
- package/src/components/carousel/CCarousel.tsx +1 -1
- package/src/components/carousel/CCarouselItem.tsx +1 -1
- package/src/components/collapse/CCollapse.tsx +1 -1
- package/src/components/date-picker/CDatePicker.tsx +1 -1
- package/src/components/date-range-picker/CDateRangePicker.tsx +4 -4
- package/src/components/date-range-picker/utils.ts +49 -0
- package/src/components/dropdown/CDropdown.tsx +3 -2
- package/src/components/dropdown/CDropdownItem.tsx +1 -2
- package/src/components/dropdown/CDropdownMenu.tsx +2 -1
- package/src/components/dropdown/CDropdownToggle.tsx +5 -4
- package/src/components/element-cover/CElementCover.tsx +16 -22
- package/src/components/element-cover/index.ts +3 -0
- package/src/components/form/CFormCheck.tsx +3 -3
- package/src/components/form/CFormControlValidation.tsx +0 -1
- package/src/components/form/CFormControlWrapper.tsx +0 -1
- package/src/components/form/CFormInput.tsx +8 -4
- package/src/components/form/CFormRange.tsx +1 -2
- package/src/components/form/CFormSelect.tsx +1 -2
- package/src/components/form/CFormTextarea.tsx +1 -2
- package/src/components/index.ts +1 -0
- package/src/components/list-group/CListGroupItem.tsx +8 -8
- package/src/components/list-group/CListGroupItem.tsx~HEAD +3 -1
- package/src/components/modal/CModal.tsx +2 -2
- package/src/components/modal/CModalHeader.tsx +3 -2
- package/src/components/multi-select/CMultiSelect.tsx +15 -74
- package/src/components/multi-select/CMultiSelectNativeSelect.tsx +1 -1
- package/src/components/multi-select/CMultiSelectOptions.tsx +2 -2
- package/src/components/multi-select/CMultiSelectSelection.tsx +1 -1
- package/src/components/multi-select/types.ts +15 -0
- package/src/components/multi-select/utils.ts +92 -0
- package/src/components/nav/CNavItem.tsx +1 -0
- package/src/components/nav/CNavLink.tsx +4 -3
- package/src/components/navbar/CNavbar.tsx +2 -1
- package/src/components/offcanvas/COffcanvas.tsx +38 -19
- package/src/components/picker/CPicker.tsx +1 -1
- package/src/components/placeholder/CPlaceholder.tsx +2 -1
- package/src/components/popover/CPopover.tsx +2 -1
- package/src/components/progress/CProgress.tsx +1 -0
- package/src/components/progress/CProgressBar.tsx +2 -1
- package/src/components/sidebar/CSidebar.tsx +3 -2
- package/src/components/smart-table/CSmartTable.tsx +263 -257
- package/src/components/smart-table/CSmartTableBody.tsx +98 -107
- package/src/components/smart-table/CSmartTableCleaner.tsx +1 -1
- package/src/components/smart-table/CSmartTableFilter.tsx +1 -3
- package/src/components/smart-table/CSmartTableHead.tsx +56 -103
- package/src/components/smart-table/CSmartTableInterface.tsx +49 -71
- package/src/components/smart-table/CSmartTableItemsPerPageSelector.tsx +1 -2
- package/src/components/smart-table/types.ts +65 -0
- package/src/components/smart-table/utils.ts +199 -0
- package/src/components/spinner/CSpinner.tsx +2 -1
- package/src/components/table/CTable.tsx +25 -59
- package/src/components/table/CTableBody.tsx +2 -1
- package/src/components/table/CTableDataCell.tsx +2 -1
- package/src/components/table/CTableFoot.tsx +2 -1
- package/src/components/table/CTableHead.tsx +2 -1
- package/src/components/table/CTableHeaderCell.tsx +2 -1
- package/src/components/table/CTableRow.tsx +2 -1
- package/src/components/table/types.ts +20 -0
- package/src/components/table/utils.ts +29 -0
- package/src/components/tabs/CTabPane.tsx +2 -1
- package/src/components/time-picker/CTimePicker.tsx +48 -23
- package/src/components/time-picker/CTimePickerRollCol.tsx +1 -1
- package/src/components/time-picker/types.ts +15 -0
- package/src/{utils/time.ts → components/time-picker/utils.ts} +43 -2
- package/src/components/toast/CToast.tsx +4 -4
- package/src/components/toast/CToastClose.tsx +2 -2
- package/src/components/toast/CToaster.tsx +2 -1
- package/src/components/tooltip/CTooltip.tsx +3 -2
- package/src/components/virtual-scroller/CVirtualScroller.tsx +32 -55
- package/src/components/widgets/CWidgetStatsA.tsx +3 -3
- package/src/components/widgets/CWidgetStatsB.tsx +4 -4
- package/src/components/widgets/CWidgetStatsC.tsx +4 -4
- package/src/components/widgets/CWidgetStatsD.tsx +4 -5
- package/src/components/widgets/CWidgetStatsE.tsx +1 -2
- package/src/components/widgets/CWidgetStatsF.tsx +3 -4
- package/src/{components/Types.tsx → props.ts} +1 -68
- package/src/types.ts +68 -0
- package/src/utils/index.ts +2 -3
- package/src/utils/isObjectInArray.ts +14 -0
- package/src/components/multi-select/CMultiSelectCleaner.tsx +0 -18
- package/src/utils/getNextSibling.ts +0 -18
- package/src/utils/getPreviousSibling.ts +0 -18
- /package/src/{utils/hooks → hooks}/index.ts +0 -0
- /package/src/{utils/hooks → hooks}/useForkedRef.ts +0 -0
- /package/src/{utils/hooks → hooks}/useStateWithCallback.ts +0 -0
|
@@ -2,64 +2,46 @@ import React, { forwardRef, MouseEvent, ReactNode } from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
4
|
import { CTableBody, CTableBodyProps } from '../table/CTableBody'
|
|
5
|
-
import {
|
|
6
|
-
import { CTableDataCell } from '../table
|
|
5
|
+
import { CFormCheck } from '../form'
|
|
6
|
+
import { CTableDataCell, CTableRow } from '../table'
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import type { Item, ScopedColumns } from './types'
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { isObjectInArray } from '../../utils'
|
|
11
|
+
|
|
12
|
+
import { getClickedColumnName, getTableDataCellProps } from './utils'
|
|
11
13
|
|
|
12
14
|
export interface CSmartTableBodyProps extends CTableBodyProps {
|
|
13
15
|
clickableRows?: boolean
|
|
14
|
-
|
|
16
|
+
columnNames: string[]
|
|
17
|
+
currentItems: Item[]
|
|
15
18
|
firstItemOnActivePageIndex: number
|
|
16
19
|
noItemsLabel?: string | ReactNode
|
|
17
|
-
onRowChecked?: (
|
|
18
|
-
onRowClick?: (
|
|
19
|
-
item: ItemInternal,
|
|
20
|
-
index: number,
|
|
21
|
-
columnName: string,
|
|
22
|
-
event: MouseEvent | boolean,
|
|
23
|
-
) => void
|
|
24
|
-
rawColumnNames: string[]
|
|
20
|
+
onRowChecked?: (item: Item, value: boolean) => void
|
|
21
|
+
onRowClick?: (item: Item, index: number, columnName: string, event: MouseEvent | boolean) => void
|
|
25
22
|
scopedColumns?: ScopedColumns
|
|
26
23
|
selectable?: boolean
|
|
24
|
+
selected?: Item[]
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
export const CSmartTableBody = forwardRef<HTMLTableSectionElement, CSmartTableBodyProps>(
|
|
30
28
|
(
|
|
31
29
|
{
|
|
32
30
|
clickableRows,
|
|
31
|
+
columnNames,
|
|
33
32
|
currentItems,
|
|
34
33
|
firstItemOnActivePageIndex,
|
|
35
34
|
noItemsLabel,
|
|
36
35
|
onRowChecked,
|
|
37
36
|
onRowClick,
|
|
38
|
-
rawColumnNames,
|
|
39
37
|
scopedColumns,
|
|
40
38
|
selectable,
|
|
39
|
+
selected,
|
|
41
40
|
...rest
|
|
42
41
|
},
|
|
43
42
|
ref,
|
|
44
43
|
) => {
|
|
45
|
-
const
|
|
46
|
-
const props = item._cellProps && {
|
|
47
|
-
...(item._cellProps['all'] && { ...item._cellProps['all'] }),
|
|
48
|
-
...(item._cellProps[colName] && { ...item._cellProps[colName] }),
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return props
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const getColumnName = (event: MouseEvent): string => {
|
|
55
|
-
const target = event.target as HTMLTextAreaElement
|
|
56
|
-
const closest = target.closest('tr')
|
|
57
|
-
const children = closest ? Array.from(closest.children) : []
|
|
58
|
-
const clickedCell = children.filter((child) => child.contains(target))[0]
|
|
59
|
-
return rawColumnNames[children.indexOf(clickedCell)]
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const colspan: number = selectable ? rawColumnNames.length + 1 : rawColumnNames.length
|
|
44
|
+
const colspan: number = selectable ? columnNames.length + 1 : columnNames.length
|
|
63
45
|
|
|
64
46
|
return (
|
|
65
47
|
<CTableBody
|
|
@@ -69,82 +51,90 @@ export const CSmartTableBody = forwardRef<HTMLTableSectionElement, CSmartTableBo
|
|
|
69
51
|
{...rest}
|
|
70
52
|
ref={ref}
|
|
71
53
|
>
|
|
72
|
-
{currentItems.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
>
|
|
88
|
-
{selectable && (
|
|
89
|
-
<CTableDataCell>
|
|
90
|
-
<CFormCheck
|
|
91
|
-
checked={item._selected ? item._selected : false}
|
|
92
|
-
onChange={(event) =>
|
|
93
|
-
onRowChecked && onRowChecked(item._id, event.target.checked)
|
|
94
|
-
}
|
|
95
|
-
/>
|
|
96
|
-
</CTableDataCell>
|
|
97
|
-
)}
|
|
98
|
-
{rawColumnNames.map((colName, index) => {
|
|
99
|
-
return (
|
|
100
|
-
(scopedColumns &&
|
|
101
|
-
scopedColumns[colName] &&
|
|
102
|
-
React.cloneElement(
|
|
103
|
-
scopedColumns[colName](item, trIndex + firstItemOnActivePageIndex),
|
|
104
|
-
{
|
|
105
|
-
key: index,
|
|
106
|
-
},
|
|
107
|
-
)) || (
|
|
108
|
-
<CTableDataCell {...tableDataCellProps(item, colName)} key={index}>
|
|
109
|
-
{String(item[colName])}
|
|
110
|
-
</CTableDataCell>
|
|
54
|
+
{currentItems.length ? (
|
|
55
|
+
currentItems.map((item: Item, trIndex) => {
|
|
56
|
+
return (
|
|
57
|
+
<React.Fragment key={trIndex}>
|
|
58
|
+
<CTableRow
|
|
59
|
+
{...(item._props && { ...item._props })}
|
|
60
|
+
{...(clickableRows && { tabIndex: 0 })}
|
|
61
|
+
onClick={(event) =>
|
|
62
|
+
onRowClick &&
|
|
63
|
+
onRowClick(
|
|
64
|
+
item,
|
|
65
|
+
trIndex + firstItemOnActivePageIndex,
|
|
66
|
+
getClickedColumnName(event.target as HTMLTextAreaElement, columnNames),
|
|
67
|
+
event,
|
|
111
68
|
)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
item,
|
|
130
|
-
trIndex + firstItemOnActivePageIndex,
|
|
131
|
-
getColumnName(event),
|
|
132
|
-
true,
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
className="p-0"
|
|
136
|
-
key={`details${trIndex}`}
|
|
137
|
-
>
|
|
138
|
-
<CTableDataCell colSpan={colspan} className="p-0" style={{ border: 0 }}>
|
|
139
|
-
{scopedColumns.details(item, trIndex + firstItemOnActivePageIndex)}
|
|
69
|
+
}
|
|
70
|
+
>
|
|
71
|
+
{selectable && (
|
|
72
|
+
<CTableDataCell>
|
|
73
|
+
<CFormCheck
|
|
74
|
+
checked={
|
|
75
|
+
selected &&
|
|
76
|
+
isObjectInArray(selected, item, ['_cellProps', '_props', '_selected'])
|
|
77
|
+
}
|
|
78
|
+
onChange={(event) => {
|
|
79
|
+
const _item = { ...item }
|
|
80
|
+
delete _item['_cellProps']
|
|
81
|
+
delete _item['_props']
|
|
82
|
+
delete _item['_selected']
|
|
83
|
+
onRowChecked && onRowChecked(_item, event.target.checked)
|
|
84
|
+
}}
|
|
85
|
+
/>
|
|
140
86
|
</CTableDataCell>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
87
|
+
)}
|
|
88
|
+
{columnNames.map((colName, index) => {
|
|
89
|
+
return (
|
|
90
|
+
(scopedColumns &&
|
|
91
|
+
scopedColumns[colName] &&
|
|
92
|
+
React.cloneElement(
|
|
93
|
+
scopedColumns[colName](item, trIndex + firstItemOnActivePageIndex),
|
|
94
|
+
{
|
|
95
|
+
key: index,
|
|
96
|
+
},
|
|
97
|
+
)) || (
|
|
98
|
+
<CTableDataCell {...getTableDataCellProps(item, colName)} key={index}>
|
|
99
|
+
{String(item[colName])}
|
|
100
|
+
</CTableDataCell>
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
})}
|
|
104
|
+
</CTableRow>
|
|
105
|
+
{scopedColumns && scopedColumns.details && (
|
|
106
|
+
<>
|
|
107
|
+
<CTableRow>
|
|
108
|
+
<CTableDataCell
|
|
109
|
+
colSpan={colspan}
|
|
110
|
+
className="p-0"
|
|
111
|
+
style={{ borderBottomWidth: 0 }}
|
|
112
|
+
tabIndex={-1}
|
|
113
|
+
></CTableDataCell>
|
|
114
|
+
</CTableRow>
|
|
115
|
+
<CTableRow
|
|
116
|
+
onClick={(event) =>
|
|
117
|
+
onRowClick &&
|
|
118
|
+
onRowClick(
|
|
119
|
+
item,
|
|
120
|
+
trIndex + firstItemOnActivePageIndex,
|
|
121
|
+
getClickedColumnName(event.target as HTMLTextAreaElement, columnNames),
|
|
122
|
+
true,
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
className="p-0"
|
|
126
|
+
key={`details${trIndex}`}
|
|
127
|
+
>
|
|
128
|
+
<CTableDataCell colSpan={colspan} className="p-0" style={{ border: 0 }}>
|
|
129
|
+
{scopedColumns.details(item, trIndex + firstItemOnActivePageIndex)}
|
|
130
|
+
</CTableDataCell>
|
|
131
|
+
</CTableRow>
|
|
132
|
+
</>
|
|
133
|
+
)}
|
|
134
|
+
</React.Fragment>
|
|
135
|
+
)
|
|
136
|
+
})
|
|
137
|
+
) : (
|
|
148
138
|
<CTableRow>
|
|
149
139
|
<CTableDataCell colSpan={colspan}>{noItemsLabel}</CTableDataCell>
|
|
150
140
|
</CTableRow>
|
|
@@ -161,9 +151,10 @@ CSmartTableBody.propTypes = {
|
|
|
161
151
|
noItemsLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
162
152
|
onRowChecked: PropTypes.func,
|
|
163
153
|
onRowClick: PropTypes.func,
|
|
164
|
-
|
|
154
|
+
columnNames: PropTypes.array.isRequired,
|
|
165
155
|
scopedColumns: PropTypes.object,
|
|
166
156
|
selectable: PropTypes.bool,
|
|
157
|
+
selected: PropTypes.array,
|
|
167
158
|
}
|
|
168
159
|
|
|
169
160
|
CSmartTableBody.displayName = 'CSmartTableBody'
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React, { forwardRef, HTMLAttributes } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
|
-
import { CFormLabel } from '../form
|
|
5
|
-
import { CFormInput } from '../form/CFormInput'
|
|
4
|
+
import { CFormInput, CFormLabel } from '../form'
|
|
6
5
|
|
|
7
6
|
interface CSmartTableFilterProps extends HTMLAttributes<HTMLInputElement> {
|
|
8
|
-
// TODO: consider to simplify ex. filterLabel --> label
|
|
9
7
|
filterLabel?: string
|
|
10
8
|
filterPlaceholder?: string
|
|
11
9
|
value?: string | number
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import React, { ElementType, forwardRef, ReactNode, useEffect, useRef, useState } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
|
+
import { CFormCheck, CFormInput } from '../form'
|
|
5
|
+
import { CTableHeaderCell, CTableRow } from '../table'
|
|
6
|
+
import { CTableHead, CTableHeadProps } from '../table/CTableHead'
|
|
7
|
+
|
|
4
8
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from './
|
|
9
|
+
getColumnKey,
|
|
10
|
+
getColumnLabel,
|
|
11
|
+
getColumnSorterState,
|
|
12
|
+
getColumnValues,
|
|
13
|
+
getTableHeaderCellProps,
|
|
14
|
+
getTableHeaderCellStyles,
|
|
15
|
+
} from './utils'
|
|
16
|
+
|
|
17
|
+
import type { ColumnFilter, ColumnFilterValue, Column, Item, Sorter, SorterValue } from './types'
|
|
12
18
|
|
|
13
|
-
import { CFormInput } from '../form/CFormInput'
|
|
14
|
-
import { CFormCheck } from '../form/CFormCheck'
|
|
15
|
-
import { CTableHead, CTableHeadProps } from '../table/CTableHead'
|
|
16
|
-
import { CTableHeaderCell } from '../table/CTableHeaderCell'
|
|
17
|
-
import { CTableRow } from '../table/CTableRow'
|
|
18
19
|
export interface CSmartTableHeadProps extends CTableHeadProps {
|
|
19
20
|
columnFilter?: boolean | ColumnFilter
|
|
20
21
|
columnFilterState?: ColumnFilterValue
|
|
@@ -26,9 +27,10 @@ export interface CSmartTableHeadProps extends CTableHeadProps {
|
|
|
26
27
|
handleFilterOnInput?: (key: string, value: string) => void
|
|
27
28
|
handleSelectAllChecked?: () => void
|
|
28
29
|
handleSort?: (key: string, index: number) => void
|
|
29
|
-
items:
|
|
30
|
+
items: Item[]
|
|
30
31
|
selectable?: boolean
|
|
31
|
-
selectAll?: boolean |
|
|
32
|
+
selectAll?: boolean | { external?: boolean }
|
|
33
|
+
selectedAll?: boolean | string
|
|
32
34
|
sorterState?: SorterValue
|
|
33
35
|
sortingIcon?: ReactNode
|
|
34
36
|
sortingIconAscending?: ReactNode
|
|
@@ -51,6 +53,7 @@ export const CSmartTableHead = forwardRef<HTMLTableSectionElement, CSmartTableHe
|
|
|
51
53
|
items,
|
|
52
54
|
selectable,
|
|
53
55
|
selectAll,
|
|
56
|
+
selectedAll,
|
|
54
57
|
sorterState,
|
|
55
58
|
sortingIcon,
|
|
56
59
|
sortingIconAscending,
|
|
@@ -59,8 +62,17 @@ export const CSmartTableHead = forwardRef<HTMLTableSectionElement, CSmartTableHe
|
|
|
59
62
|
},
|
|
60
63
|
ref,
|
|
61
64
|
) => {
|
|
65
|
+
const selectAllcheckboxRef = useRef<HTMLInputElement>(null)
|
|
62
66
|
const [refresh, setRefresh] = useState(false)
|
|
63
67
|
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (selectedAll === 'indeterminate') {
|
|
70
|
+
if (selectAllcheckboxRef.current) selectAllcheckboxRef.current.indeterminate = true
|
|
71
|
+
} else {
|
|
72
|
+
if (selectAllcheckboxRef.current) selectAllcheckboxRef.current.indeterminate = false
|
|
73
|
+
}
|
|
74
|
+
}, [selectedAll])
|
|
75
|
+
|
|
64
76
|
useEffect(() => {
|
|
65
77
|
if (columnFilterState && Object.keys(columnFilterState).length === 0) {
|
|
66
78
|
setRefresh(true)
|
|
@@ -77,108 +89,45 @@ export const CSmartTableHead = forwardRef<HTMLTableSectionElement, CSmartTableHe
|
|
|
77
89
|
}
|
|
78
90
|
}, [refresh])
|
|
79
91
|
|
|
80
|
-
const tableHeaderCellProps = (column: Column | string) => {
|
|
81
|
-
if (typeof column === 'object' && column._props) {
|
|
82
|
-
return column._props
|
|
83
|
-
}
|
|
84
|
-
return {}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const tableHeaderCellStyles = (column: Column | string) => {
|
|
88
|
-
const style = { verticalAlign: 'middle', overflow: 'hidden', cursor: '' }
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
columnSorter &&
|
|
92
|
-
(typeof column !== 'object' ||
|
|
93
|
-
(typeof column === 'object' && (typeof column.sorter === 'undefined' || column.sorter)))
|
|
94
|
-
) {
|
|
95
|
-
style.cursor = 'pointer'
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (typeof column === 'object' && column._style) {
|
|
99
|
-
return { ...style, ...column._style }
|
|
100
|
-
}
|
|
101
|
-
return style
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const pretifyName = (name: string) => {
|
|
105
|
-
return name
|
|
106
|
-
.replace(/[-_.]/g, ' ')
|
|
107
|
-
.replace(/ +/g, ' ')
|
|
108
|
-
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
109
|
-
.split(' ')
|
|
110
|
-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
111
|
-
.join(' ')
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const label = (column: Column | string) =>
|
|
115
|
-
typeof column === 'object'
|
|
116
|
-
? column.label !== undefined
|
|
117
|
-
? column.label
|
|
118
|
-
: pretifyName(column.key)
|
|
119
|
-
: pretifyName(column)
|
|
120
|
-
|
|
121
|
-
const key = (column: Column | string) => (typeof column === 'object' ? column.key : column)
|
|
122
|
-
|
|
123
|
-
const getColumnSorterState = (key: string): string | number => {
|
|
124
|
-
if (sorterState && sorterState.column === key) {
|
|
125
|
-
if (sorterState.state) {
|
|
126
|
-
return sorterState.state
|
|
127
|
-
}
|
|
128
|
-
return 0
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return 0
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const getValues = (items: ItemInternal[], key: string) => {
|
|
135
|
-
return items.map((a) => a[key])
|
|
136
|
-
}
|
|
137
|
-
|
|
138
92
|
const columnSorterIcon = (column: Column | string) => {
|
|
139
|
-
if (getColumnSorterState(
|
|
93
|
+
if (getColumnSorterState(getColumnKey(column), sorterState) === 0) {
|
|
140
94
|
return <span className="opacity-25 float-end me-1">{sortingIcon}</span>
|
|
141
95
|
}
|
|
142
|
-
|
|
96
|
+
|
|
97
|
+
if (getColumnSorterState(getColumnKey(column), sorterState) === 'asc') {
|
|
143
98
|
return <span className="float-end me-1">{sortingIconAscending}</span>
|
|
144
99
|
}
|
|
145
|
-
|
|
100
|
+
|
|
101
|
+
if (getColumnSorterState(getColumnKey(column), sorterState) === 'desc') {
|
|
146
102
|
return <span className="float-end me-1">{sortingIconDescending}</span>
|
|
147
103
|
}
|
|
104
|
+
|
|
148
105
|
return
|
|
149
106
|
}
|
|
150
107
|
|
|
151
|
-
const checkboxRef = useRef<HTMLInputElement>(null)
|
|
152
|
-
|
|
153
|
-
useEffect(() => {
|
|
154
|
-
if (selectAll === 'indeterminate') {
|
|
155
|
-
if (checkboxRef.current) checkboxRef.current.indeterminate = true
|
|
156
|
-
} else {
|
|
157
|
-
if (checkboxRef.current) checkboxRef.current.indeterminate = false
|
|
158
|
-
}
|
|
159
|
-
}, [selectAll])
|
|
160
|
-
|
|
161
108
|
return (
|
|
162
109
|
<Component {...rest} ref={ref}>
|
|
163
110
|
<CTableRow>
|
|
164
111
|
{selectable && (
|
|
165
112
|
<CTableHeaderCell>
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
113
|
+
{selectAll && (
|
|
114
|
+
<CFormCheck
|
|
115
|
+
checked={typeof selectedAll === 'boolean' ? selectedAll : false}
|
|
116
|
+
onChange={() => handleSelectAllChecked && handleSelectAllChecked()}
|
|
117
|
+
ref={selectAllcheckboxRef}
|
|
118
|
+
/>
|
|
119
|
+
)}
|
|
171
120
|
</CTableHeaderCell>
|
|
172
121
|
)}
|
|
173
122
|
{columns.map((column: Column | string, index: number) => {
|
|
174
123
|
return (
|
|
175
124
|
<CTableHeaderCell
|
|
176
|
-
{...
|
|
177
|
-
onClick={() => handleSort && handleSort(
|
|
178
|
-
style={
|
|
125
|
+
{...getTableHeaderCellProps(column)}
|
|
126
|
+
onClick={() => handleSort && handleSort(getColumnKey(column), index)}
|
|
127
|
+
style={getTableHeaderCellStyles(column, columnSorter)}
|
|
179
128
|
key={index}
|
|
180
129
|
>
|
|
181
|
-
<div className="d-inline">{
|
|
130
|
+
<div className="d-inline">{getColumnLabel(column)}</div>
|
|
182
131
|
{columnSorter &&
|
|
183
132
|
(typeof column !== 'object'
|
|
184
133
|
? true
|
|
@@ -195,7 +144,7 @@ export const CSmartTableHead = forwardRef<HTMLTableSectionElement, CSmartTableHe
|
|
|
195
144
|
{selectable && <CTableHeaderCell></CTableHeaderCell>}
|
|
196
145
|
{columns.map((column: Column | string, index: number) => {
|
|
197
146
|
return (
|
|
198
|
-
<CTableHeaderCell {...
|
|
147
|
+
<CTableHeaderCell {...getTableHeaderCellProps(column)} key={index}>
|
|
199
148
|
{(
|
|
200
149
|
typeof column !== 'object'
|
|
201
150
|
? true
|
|
@@ -206,31 +155,34 @@ export const CSmartTableHead = forwardRef<HTMLTableSectionElement, CSmartTableHe
|
|
|
206
155
|
typeof column !== 'string' && typeof column.filter === 'function' ? (
|
|
207
156
|
!refresh &&
|
|
208
157
|
column.filter(
|
|
209
|
-
|
|
158
|
+
getColumnValues(items, getColumnKey(column)),
|
|
210
159
|
(value: any) =>
|
|
211
160
|
handleOnCustomFilterChange &&
|
|
212
|
-
handleOnCustomFilterChange(
|
|
161
|
+
handleOnCustomFilterChange(getColumnKey(column), value),
|
|
213
162
|
)
|
|
214
163
|
) : (
|
|
215
164
|
<CFormInput
|
|
216
165
|
size="sm"
|
|
217
166
|
onInput={(event) =>
|
|
218
167
|
handleFilterOnInput &&
|
|
219
|
-
handleFilterOnInput(
|
|
168
|
+
handleFilterOnInput(
|
|
169
|
+
getColumnKey(column),
|
|
170
|
+
(event.target as HTMLInputElement).value,
|
|
171
|
+
)
|
|
220
172
|
}
|
|
221
173
|
onChange={(event) =>
|
|
222
174
|
handleFilterOnChange &&
|
|
223
175
|
handleFilterOnChange(
|
|
224
|
-
|
|
176
|
+
getColumnKey(column),
|
|
225
177
|
(event.target as HTMLInputElement).value,
|
|
226
178
|
)
|
|
227
179
|
}
|
|
228
180
|
value={
|
|
229
|
-
columnFilterState && columnFilterState[
|
|
230
|
-
? columnFilterState[
|
|
181
|
+
columnFilterState && columnFilterState[getColumnKey(column)]
|
|
182
|
+
? columnFilterState[getColumnKey(column)]
|
|
231
183
|
: ''
|
|
232
184
|
}
|
|
233
|
-
aria-label={`column name: '${
|
|
185
|
+
aria-label={`column name: '${getColumnLabel(column)}' filter input`}
|
|
234
186
|
/>
|
|
235
187
|
)
|
|
236
188
|
) : (
|
|
@@ -258,7 +210,8 @@ CSmartTableHead.propTypes = {
|
|
|
258
210
|
handleSelectAllChecked: PropTypes.func,
|
|
259
211
|
handleSort: PropTypes.func,
|
|
260
212
|
selectable: PropTypes.bool,
|
|
261
|
-
selectAll: PropTypes.oneOfType([PropTypes.bool, PropTypes.
|
|
213
|
+
selectAll: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
|
|
214
|
+
selectedAll: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
|
|
262
215
|
sorterState: PropTypes.object,
|
|
263
216
|
sortingIcon: PropTypes.node,
|
|
264
217
|
sortingIconAscending: PropTypes.node,
|