Skip to content

Commit ea31988

Browse files
authored
Merge pull request #379 from vtfk/table-customrender-callback
Table customrender callback
2 parents 1becc9c + 7352afe commit ea31988

File tree

2 files changed

+67
-16
lines changed

2 files changed

+67
-16
lines changed

src/ui/Table/Table.stories.js

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,14 @@ export function CustomStyle () {
123123
{
124124
label: 'DisplayName',
125125
value: 'itemTitle',
126+
tooltip: 'This is a tooltip for the displayName header',
127+
itemTooltip: 'itemSecondary',
126128
style: { textTransform: 'Uppercase', color: 'blue' }
127129
},
128130
{
129131
label: 'Username',
130132
value: 'itemSecondary',
133+
itemTooltip: 'This is just a text tooltip that dont match any data',
131134
itemStyle: { backgroundColor: 'pink', textAlign: 'center' }
132135
},
133136
{
@@ -191,7 +194,7 @@ export function CustomRendering () {
191194
<Button style={{ marginLeft: 'auto', marginRight: 'auto' }}>{header.label}</Button>
192195
)
193196
},
194-
itemRender: (item, index, header) => {
197+
itemRender: (value, item, index, header) => {
195198
return (
196199
<div>
197200
<IconButton
@@ -200,24 +203,46 @@ export function CustomRendering () {
200203
console.log('At index', index)
201204
console.log('Under header', header)
202205
console.log('Event', e)
206+
207+
e.preventDefault()
208+
e.stopPropagation()
203209
}}
204-
/>
210+
>{value.toString()}
211+
</IconButton>
205212
</div>
206213
)
207214
}
208215
}
209216
]
210217

211218
return (
212-
<Table
213-
headers={customHeaders}
214-
items={items}
215-
itemId='itemSecondary'
216-
showSelect
217-
selectOnClick
218-
onSelectedIdsChanged={ids => console.log('Selected ids', ids)}
219-
onSelectedItemsChanged={items => console.log('Selected items:', items)}
220-
/>
219+
<div>
220+
<h2 style={{ margin: '0.2rem 0' }}>Custom rendering</h2>
221+
Works by adding a callback functions to the header entries that returns JSX
222+
<h4 style={{ marginBottom: '0.2rem' }}>Custom header renderer</h4>
223+
{'render: (header) => { return ({<>{ header.label }</>}){}}'}
224+
<ul style={{ marginTop: '0.3rem' }}>
225+
<li>header = Header object</li>
226+
</ul>
227+
<h4 style={{ marginBottom: '0.2rem' }}>Custom item renderer</h4>
228+
{/* eslint-disable-next-line */}
229+
{'itemRender: (value, item, header, index) => { return (<>{`${item.firstname} ${item.lastName}`}</>)}'}
230+
<ul style={{ marginTop: '0.3rem' }}>
231+
<li>value = Value that would have been displayed in regular rendering</li>
232+
<li>item = Item object for the row</li>
233+
<li>header = Header object for the column</li>
234+
<li>index = Array index of the item</li>
235+
</ul>
236+
<Table
237+
headers={customHeaders}
238+
items={items}
239+
itemId='itemSecondary'
240+
showSelect
241+
selectOnClick
242+
onSelectedIdsChanged={ids => console.log('Selected ids', ids)}
243+
onSelectedItemsChanged={items => console.log('Selected items:', items)}
244+
/>
245+
</div>
221246
)
222247
}
223248

src/ui/Table/index.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,25 +150,41 @@ export function Table ({ headers, items, itemId = '_id', selectedIds, mode, show
150150
return header.label || ''
151151
}
152152

153+
// Gets a value from a given path in an object
154+
function getValueAsString (item, path) {
155+
try {
156+
// Retreive the value
157+
let value = get(item, path)
158+
159+
// If item value is not string, convert it before returning
160+
if (typeof value === 'object') value = JSON.stringify(value)
161+
else if (typeof value !== 'string' && value.toString) {
162+
value = value.toString()
163+
}
164+
165+
return value
166+
} catch { return '' }
167+
}
168+
153169
// Gets the appropriate value to render for a item
154170
function getItemValue (item, header, index) {
155171
// If no item or header, just return a empty string
156172
if (!item || !header) return ''
157173

174+
// Retreive the value
175+
const value = get(item, header.value)
176+
158177
// If the header has a render function for the item
159178
if (header.itemRender && typeof header.itemRender === 'function') {
160179
try {
161-
const result = header.itemRender(item, index, header)
180+
const result = header.itemRender(value, item, header, index)
162181
if (result && typeof result === 'object') return result
163182
} catch (err) { console.error('Error rendering item', err) }
164183
}
165184

166185
// If the item contain a element
167186
if (item._elements?.[header.value]) return item._elements?.[header.value]
168187

169-
// Retreive the value
170-
const value = get(item, header.value)
171-
172188
// If the item has no matching value
173189
if (!value) return ''
174190

@@ -207,7 +223,12 @@ export function Table ({ headers, items, itemId = '_id', selectedIds, mode, show
207223
{
208224
// Render all headers
209225
headers.map((header) =>
210-
<th key={nanoid()} className={mergeClasses(headerClass, header.class)} style={mergeStyles(headerStyle, header.style)}>
226+
<th
227+
key={nanoid()}
228+
className={mergeClasses(headerClass, header.class)}
229+
style={mergeStyles(headerStyle, header.style)}
230+
title={getValueAsString(header, header.itemTooltip) || header.tooltip}
231+
>
211232
{
212233
getHeaderValue(header)
213234
}
@@ -251,6 +272,7 @@ export function Table ({ headers, items, itemId = '_id', selectedIds, mode, show
251272
key={nanoid()}
252273
className={mergeClasses(itemClass, header.itemClass)}
253274
style={mergeStyles(itemStyle, header.itemStyle)}
275+
title={getValueAsString(item, header.itemTooltip) || header.itemTooltip}
254276
>
255277
{getItemValue(item, header, index)}
256278
</td>
@@ -362,6 +384,10 @@ Table.propTypes = {
362384
itemStyle: PropTypes.object,
363385
class: PropTypes.string,
364386
itemClass: PropTypes.string,
387+
render: PropTypes.func,
388+
itemRender: PropTypes.func,
389+
tooltip: PropTypes.string,
390+
itemTooltip: PropTypes.string,
365391
element: PropTypes.element
366392
})).isRequired,
367393
isLoading: PropTypes.bool,

0 commit comments

Comments
 (0)