nitro-web 0.2.0 → 0.2.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.
|
@@ -164,7 +164,7 @@ export const Dropdown = forwardRef(function Dropdown({
|
|
|
164
164
|
' nitro-dropdown' +
|
|
165
165
|
(className ? ` ${className}` : '')
|
|
166
166
|
}
|
|
167
|
-
onClick={(e) => e.stopPropagation()} // required for dropdowns inside row links
|
|
167
|
+
onClick={(e) => { e.stopPropagation(); e.preventDefault() }} // required for dropdowns inside row links
|
|
168
168
|
ref={dropdownRef}
|
|
169
169
|
css={style}
|
|
170
170
|
>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JSX, useState, useCallback, Fragment, useMemo, useEffect } from 'react'
|
|
2
2
|
import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react'
|
|
3
3
|
import { Checkbox, queryObject, queryString, Spinner, twMerge, LoadingWithDots, LoadingOverlay } from 'nitro-web'
|
|
4
|
-
import { useLocation, useNavigate } from 'react-router-dom'
|
|
4
|
+
import { useLocation, useNavigate, Link } from 'react-router-dom'
|
|
5
5
|
|
|
6
6
|
export type TableRowType = 'row' | 'loading' | 'empty' | 'thead'
|
|
7
7
|
|
|
@@ -36,6 +36,7 @@ export type TableProps<T> = {
|
|
|
36
36
|
rowSideColor?: (row: T|undefined, type: TableRowType) => { className: string, width: number }
|
|
37
37
|
rowGap?: number
|
|
38
38
|
rowOnClick?: (row: T) => void
|
|
39
|
+
rowLink?: (row: T) => string
|
|
39
40
|
columnGap?: number
|
|
40
41
|
columnPaddingX?: number
|
|
41
42
|
className?: string
|
|
@@ -67,6 +68,7 @@ export function Table<T extends TableRow>({
|
|
|
67
68
|
rowSideColor,
|
|
68
69
|
rowGap=0,
|
|
69
70
|
rowOnClick,
|
|
71
|
+
rowLink,
|
|
70
72
|
columnGap=11,
|
|
71
73
|
columnPaddingX=11,
|
|
72
74
|
// Class names
|
|
@@ -244,97 +246,97 @@ export function Table<T extends TableRow>({
|
|
|
244
246
|
{
|
|
245
247
|
rowsToRender.map((row: T, i: number) => {
|
|
246
248
|
const isSelected = selectedRowIds.includes(row._id || '')
|
|
249
|
+
const Element = (rowLink ? Link : 'div') as React.ElementType
|
|
250
|
+
const extraProps = rowLink ? { to: rowLink(row) } : { onClick: rowOnClick ? () => rowOnClick(row) : undefined }
|
|
247
251
|
return (
|
|
248
|
-
<
|
|
252
|
+
<Element
|
|
253
|
+
{...extraProps}
|
|
249
254
|
key={`${row._id}-${i}`}
|
|
250
255
|
id={`row-${row._id}-${i}`}
|
|
251
|
-
onClick={rowOnClick ? () => rowOnClick(row) : undefined}
|
|
252
256
|
className={twMerge(
|
|
253
|
-
`table-row relative ${rowOnClick ? 'cursor-pointer' : ''} ${isSelected ? 'is-selected' : ''}`,
|
|
257
|
+
`table-row relative ${(rowOnClick || rowLink) ? 'cursor-pointer' : ''} ${isSelected ? 'is-selected' : ''}`,
|
|
254
258
|
rowClassName,
|
|
255
259
|
rowClassNameFn ? rowClassNameFn(row, i) : ''
|
|
256
260
|
)}
|
|
257
261
|
>
|
|
258
|
-
{
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
262
|
+
{columns.map((col, j) => {
|
|
263
|
+
const rowType = row._id ? 'row' : isLoading ? 'loading' : 'empty'
|
|
264
|
+
const { pl, pr, sideColor } = getColumnPadding(j, isLoading ? undefined : row, rowType)
|
|
265
|
+
if (col.isHidden) return <Fragment key={j} />
|
|
266
|
+
return (
|
|
267
|
+
<div
|
|
268
|
+
key={j}
|
|
269
|
+
style={{ height: rowHeightMin, paddingLeft: pl, paddingRight: pr }}
|
|
270
|
+
className={twMerge(
|
|
271
|
+
_columnClassName,
|
|
272
|
+
getAlignClass(col.align),
|
|
273
|
+
columnClassName,
|
|
274
|
+
columnClassNameFn ? columnClassNameFn(col, row, i) : '',
|
|
275
|
+
col.className,
|
|
276
|
+
isSelected ? `bg-gray-50 ${columnSelectedClassName||''}` : ''
|
|
277
|
+
)}
|
|
278
|
+
>
|
|
279
|
+
<div
|
|
280
|
+
// pl:sideColorPadding was originally here
|
|
281
|
+
style={{ maxHeight: rowContentHeightMax }}
|
|
267
282
|
className={twMerge(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
col.className,
|
|
273
|
-
isSelected ? `bg-gray-50 ${columnSelectedClassName||''}` : ''
|
|
283
|
+
rowContentHeightMax ? 'overflow-hidden' : '',
|
|
284
|
+
getLineClampClassName(col.rowLinesMax),
|
|
285
|
+
col.overflow ? 'overflow-visible' : '',
|
|
286
|
+
col.innerClassName
|
|
274
287
|
)}
|
|
275
288
|
>
|
|
276
|
-
|
|
277
|
-
//
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
<Fragment>
|
|
323
|
-
<Spinner className="border-gray-500" />
|
|
324
|
-
<LoadingWithDots message={loadingMessage} />
|
|
325
|
-
</Fragment>
|
|
326
|
-
) : (!row._id && isLoading && showLoadingInline) ? (
|
|
327
|
-
showLoadingInline
|
|
328
|
-
) : null
|
|
329
|
-
}
|
|
330
|
-
</div>
|
|
331
|
-
}
|
|
332
|
-
</div>
|
|
289
|
+
{
|
|
290
|
+
// Side color
|
|
291
|
+
sideColor &&
|
|
292
|
+
<div
|
|
293
|
+
className={`absolute top-0 left-0 h-full ${sideColor?.className||''}`}
|
|
294
|
+
style={{ width: sideColor.width }}
|
|
295
|
+
/>
|
|
296
|
+
}
|
|
297
|
+
{
|
|
298
|
+
// Rows (content hidden when loading inline)
|
|
299
|
+
row._id &&
|
|
300
|
+
<div className={isLoading && showLoadingInline ? 'opacity-0 pointer-events-none' : ''}>
|
|
301
|
+
{
|
|
302
|
+
col.value == 'checkbox'
|
|
303
|
+
? <Checkbox
|
|
304
|
+
size={checkboxSize}
|
|
305
|
+
name={`checkbox-${row._id}`}
|
|
306
|
+
onChange={(e) => onSelect(row?._id || '', e.target.checked)}
|
|
307
|
+
checked={selectedRowIds.includes(row?._id || '')}
|
|
308
|
+
onClick={(e) => e.stopPropagation()}
|
|
309
|
+
hitboxPadding={5}
|
|
310
|
+
className='!m-0 py-[5px]' // py-5 is required for hitbox (restricted to tabel cell height)
|
|
311
|
+
checkboxClassName={twMerge('border-foreground shadow-[0_1px_2px_0px_#0000001c]', checkboxClassName)}
|
|
312
|
+
/>
|
|
313
|
+
: generateTd(col, row, i, i == rows.length - 1)
|
|
314
|
+
}
|
|
315
|
+
</div>
|
|
316
|
+
}
|
|
317
|
+
{
|
|
318
|
+
// Show "no records" or "loading" text in the first column
|
|
319
|
+
j == 0 && (!row._id || isLoading) &&
|
|
320
|
+
<div className={'absolute top-0 h-full flex items-center justify-center gap-3 text-sm text-gray-500'}>
|
|
321
|
+
{
|
|
322
|
+
(!row._id && !isLoading) ? (
|
|
323
|
+
'No records found.'
|
|
324
|
+
) : (!row._id && isLoading && showLoadingInline === true) ? (
|
|
325
|
+
<Fragment>
|
|
326
|
+
<Spinner className="border-gray-500" />
|
|
327
|
+
<LoadingWithDots message={loadingMessage} />
|
|
328
|
+
</Fragment>
|
|
329
|
+
) : (!row._id && isLoading && showLoadingInline) ? (
|
|
330
|
+
showLoadingInline
|
|
331
|
+
) : null
|
|
332
|
+
}
|
|
333
|
+
</div>
|
|
334
|
+
}
|
|
333
335
|
</div>
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
</
|
|
336
|
+
</div>
|
|
337
|
+
)
|
|
338
|
+
})}
|
|
339
|
+
</Element>
|
|
338
340
|
)
|
|
339
341
|
})
|
|
340
342
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitro-web",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"repository": "github:boycce/nitro-web",
|
|
5
5
|
"homepage": "https://boycce.github.io/nitro-web/",
|
|
6
6
|
"description": "Nitro is a battle-tested, modular base project to turbocharge your projects, styled using Tailwind 🚀",
|