nitro-web 0.2.0 → 0.2.2

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
- <div
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
- columns.map((col, j) => {
260
- const rowType = row._id ? 'row' : isLoading ? 'loading' : 'empty'
261
- const { pl, pr, sideColor } = getColumnPadding(j, isLoading ? undefined : row, rowType)
262
- if (col.isHidden) return <Fragment key={j} />
263
- return (
264
- <div
265
- key={j}
266
- style={{ height: rowHeightMin, paddingLeft: pl, paddingRight: pr }}
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
- _columnClassName,
269
- getAlignClass(col.align),
270
- columnClassName,
271
- columnClassNameFn ? columnClassNameFn(col, row, i) : '',
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
- <div
277
- // pl:sideColorPadding was originally here
278
- style={{ maxHeight: rowContentHeightMax }}
279
- className={twMerge(
280
- rowContentHeightMax ? 'overflow-hidden' : '',
281
- getLineClampClassName(col.rowLinesMax),
282
- col.overflow ? 'overflow-visible' : '',
283
- col.innerClassName
284
- )}
285
- >
286
- {
287
- // Side color
288
- sideColor &&
289
- <div
290
- className={`absolute top-0 left-0 h-full ${sideColor?.className||''}`}
291
- style={{ width: sideColor.width }}
292
- />
293
- }
294
- {
295
- // Rows (content hidden when loading inline)
296
- row._id &&
297
- <div className={isLoading && showLoadingInline ? 'opacity-0 pointer-events-none' : ''}>
298
- {
299
- col.value == 'checkbox'
300
- ? <Checkbox
301
- size={checkboxSize}
302
- name={`checkbox-${row._id}`}
303
- onChange={(e) => onSelect(row?._id || '', e.target.checked)}
304
- checked={selectedRowIds.includes(row?._id || '')}
305
- onClick={(e) => e.stopPropagation()}
306
- hitboxPadding={5}
307
- className='!m-0 py-[5px]' // py-5 is required for hitbox (restricted to tabel cell height)
308
- checkboxClassName={twMerge('border-foreground shadow-[0_1px_2px_0px_#0000001c]', checkboxClassName)}
309
- />
310
- : generateTd(col, row, i, i == rows.length - 1)
311
- }
312
- </div>
313
- }
314
- {
315
- // Show "no records" or "loading" text in the first column
316
- j == 0 && (!row._id || isLoading) &&
317
- <div className={'absolute top-0 h-full flex items-center justify-center gap-3 text-sm text-gray-500'}>
318
- {
319
- (!row._id && !isLoading) ? (
320
- 'No records found.'
321
- ) : (!row._id && isLoading && showLoadingInline === true) ? (
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
- </div>
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.0",
3
+ "version": "0.2.2",
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 🚀",
@@ -64,7 +64,7 @@
64
64
  },
65
65
  "peerDependencies": {
66
66
  "@stripe/stripe-js": "^1.34.0",
67
- "monastery": "^3.5.13",
67
+ "monastery": "^4.0.1",
68
68
  "stripe": "^9.16.0"
69
69
  },
70
70
  "_peers-are-packages-that-will-be-used-in-the-host-repo-too": "",