@fastnd/components 1.0.30 → 1.0.32

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 (57) hide show
  1. package/dist/components/QuickAccessCard/QuickAccessCard.d.ts +12 -0
  2. package/dist/components/ScoreBar/ScoreBar.d.ts +8 -0
  3. package/dist/components/index.d.ts +2 -0
  4. package/dist/examples/dashboard/StatusDonutChart/StatusDonutChart.tsx +41 -56
  5. package/dist/examples/data-visualization/CardCarouselPanel/CardCarouselPanel.tsx +171 -0
  6. package/dist/examples/data-visualization/CellRenderers/CellRenderers.tsx +175 -0
  7. package/dist/examples/data-visualization/ColumnConfigPopover/ColumnConfigPopover.tsx +124 -0
  8. package/dist/examples/data-visualization/DataCardView/DataCardView.tsx +223 -0
  9. package/dist/examples/data-visualization/DataExplorerPagination/DataExplorerPagination.tsx +143 -0
  10. package/dist/examples/data-visualization/DataExplorerToolbar/DataExplorerToolbar.tsx +88 -0
  11. package/dist/examples/data-visualization/DataListView/DataListView.tsx +246 -0
  12. package/dist/examples/data-visualization/DataTableView/DataTableView.tsx +449 -0
  13. package/dist/examples/data-visualization/DataVisualizationPage/DataVisualizationPage.tsx +140 -0
  14. package/dist/examples/data-visualization/FilterChipGroup/FilterChipGroup.tsx +125 -0
  15. package/dist/examples/data-visualization/MoreFiltersPopover/MoreFiltersPopover.tsx +132 -0
  16. package/dist/examples/data-visualization/constants.ts +587 -0
  17. package/dist/examples/data-visualization/hooks/use-column-config.ts +76 -0
  18. package/dist/examples/data-visualization/hooks/use-data-explorer-state.ts +313 -0
  19. package/dist/examples/data-visualization/index.ts +1 -0
  20. package/dist/examples/data-visualization/types.ts +99 -0
  21. package/dist/examples/quickaccess/QuickAccess/QuickAccess.tsx +97 -0
  22. package/dist/examples/quickaccess/index.ts +2 -0
  23. package/dist/examples/quickaccess/types.ts +11 -0
  24. package/dist/fastnd-components.js +5708 -5590
  25. package/package.json +1 -1
  26. package/dist/examples/data-explorer/CardCarouselPanel/CardCarouselPanel.tsx +0 -197
  27. package/dist/examples/data-explorer/CardView/CardView.tsx +0 -168
  28. package/dist/examples/data-explorer/ColumnConfigPopover/ColumnConfigPopover.tsx +0 -157
  29. package/dist/examples/data-explorer/DataExplorerEmpty/DataExplorerEmpty.tsx +0 -56
  30. package/dist/examples/data-explorer/DataExplorerPage/DataExplorerPage.tsx +0 -101
  31. package/dist/examples/data-explorer/DataExplorerPagination/DataExplorerPagination.tsx +0 -129
  32. package/dist/examples/data-explorer/DataExplorerToolbar/DataExplorerToolbar.tsx +0 -143
  33. package/dist/examples/data-explorer/DomainSwitcher/DomainSwitcher.tsx +0 -36
  34. package/dist/examples/data-explorer/ExpansionRows/ExpansionRows.tsx +0 -180
  35. package/dist/examples/data-explorer/FilterChip/FilterChip.tsx +0 -85
  36. package/dist/examples/data-explorer/FilterPopoverContent/FilterPopoverContent.tsx +0 -73
  37. package/dist/examples/data-explorer/ListView/ListView.tsx +0 -305
  38. package/dist/examples/data-explorer/MoreFiltersPopover/MoreFiltersPopover.tsx +0 -113
  39. package/dist/examples/data-explorer/TableView/TableView.tsx +0 -193
  40. package/dist/examples/data-explorer/cells/CellRenderer.tsx +0 -147
  41. package/dist/examples/data-explorer/cells/CurrencyCell.tsx +0 -31
  42. package/dist/examples/data-explorer/cells/DoubleTextCell.tsx +0 -27
  43. package/dist/examples/data-explorer/cells/ExpandButton.tsx +0 -67
  44. package/dist/examples/data-explorer/cells/InventoryBadgeCell.tsx +0 -52
  45. package/dist/examples/data-explorer/cells/LinkCell.tsx +0 -42
  46. package/dist/examples/data-explorer/cells/ScoreBar.tsx +0 -50
  47. package/dist/examples/data-explorer/cells/StatusBadgeCell.tsx +0 -39
  48. package/dist/examples/data-explorer/cells/TextCell.tsx +0 -35
  49. package/dist/examples/data-explorer/cells/index.ts +0 -26
  50. package/dist/examples/data-explorer/domains/applications.ts +0 -225
  51. package/dist/examples/data-explorer/domains/customers.ts +0 -267
  52. package/dist/examples/data-explorer/domains/index.ts +0 -26
  53. package/dist/examples/data-explorer/domains/products.ts +0 -1116
  54. package/dist/examples/data-explorer/domains/projects.ts +0 -205
  55. package/dist/examples/data-explorer/hooks/use-data-explorer-state.ts +0 -371
  56. package/dist/examples/data-explorer/index.ts +0 -3
  57. package/dist/examples/data-explorer/types.ts +0 -239
@@ -1,147 +0,0 @@
1
- import * as React from 'react'
2
- import { FavoriteButton } from '@/components/FavoriteButton/FavoriteButton'
3
- import type { ColumnDef } from '../types'
4
- import { TextCell } from './TextCell'
5
- import { DoubleTextCell } from './DoubleTextCell'
6
- import { LinkCell } from './LinkCell'
7
- import { StatusBadgeCell } from './StatusBadgeCell'
8
- import { CurrencyCell } from './CurrencyCell'
9
- import { InventoryBadgeCell } from './InventoryBadgeCell'
10
- import { ScoreBar } from './ScoreBar'
11
- import { ExpandButton } from './ExpandButton'
12
-
13
- interface CellRendererProps {
14
- column: ColumnDef
15
- columnKey: string
16
- row: Record<string, unknown>
17
- expanded?: boolean
18
- onToggleExpand?: () => void
19
- onToggleFavorite?: () => void
20
- isFavorite?: boolean
21
- className?: string
22
- }
23
-
24
- const CellRenderer = ({
25
- column,
26
- columnKey,
27
- row,
28
- expanded = false,
29
- onToggleExpand,
30
- onToggleFavorite,
31
- isFavorite = false,
32
- className,
33
- }: CellRendererProps) => {
34
- const value = row[columnKey]
35
-
36
- switch (column.type) {
37
- case 'text': {
38
- return (
39
- <TextCell
40
- value={value as string | null | undefined}
41
- maxLines={column.rowLines}
42
- className={className}
43
- />
44
- )
45
- }
46
-
47
- case 'double-text': {
48
- const secondary = column.secondary ? (row[column.secondary] as string | null | undefined) : undefined
49
- return (
50
- <DoubleTextCell
51
- primary={value as string | null | undefined}
52
- secondary={secondary}
53
- className={className}
54
- />
55
- )
56
- }
57
-
58
- case 'link': {
59
- return (
60
- <LinkCell
61
- value={value as string | null | undefined}
62
- className={className}
63
- />
64
- )
65
- }
66
-
67
- case 'status-badge': {
68
- return (
69
- <StatusBadgeCell
70
- value={value as string | null | undefined}
71
- statusMap={column.statusMap}
72
- className={className}
73
- />
74
- )
75
- }
76
-
77
- case 'currency': {
78
- const currency = column.currencyField
79
- ? (row[column.currencyField] as string | undefined)
80
- : 'EUR'
81
- return (
82
- <CurrencyCell
83
- value={value as number | null | undefined}
84
- currency={currency}
85
- className={className}
86
- />
87
- )
88
- }
89
-
90
- case 'inventory': {
91
- return (
92
- <InventoryBadgeCell
93
- value={value as number | null | undefined}
94
- levelFn={column.levelFn as ((v: number) => string) | undefined}
95
- formatFn={column.formatFn as ((v: number) => string) | undefined}
96
- className={className}
97
- />
98
- )
99
- }
100
-
101
- case 'progress': {
102
- const numValue = typeof value === 'number' ? value : 0
103
- return <ScoreBar value={numValue} className={className} />
104
- }
105
-
106
- case 'favorite': {
107
- return (
108
- <FavoriteButton
109
- pressed={isFavorite}
110
- itemName={String(row['id'] ?? '')}
111
- onPressedChange={() => onToggleFavorite?.()}
112
- className={className}
113
- />
114
- )
115
- }
116
-
117
- case 'expand': {
118
- const items = value
119
- const count = Array.isArray(items) ? items.length : 0
120
-
121
- if (count === 0) return null
122
-
123
- return (
124
- <ExpandButton
125
- count={count}
126
- label={column.expandLabel ?? columnKey}
127
- icon={column.expandIcon}
128
- expanded={expanded}
129
- onToggle={onToggleExpand}
130
- className={className}
131
- />
132
- )
133
- }
134
-
135
- default: {
136
- const fallback = value != null ? String(value) : ''
137
- return (
138
- <TextCell value={fallback} className={className} />
139
- )
140
- }
141
- }
142
- }
143
-
144
- CellRenderer.displayName = 'CellRenderer'
145
-
146
- export { CellRenderer }
147
- export type { CellRendererProps }
@@ -1,31 +0,0 @@
1
- import * as React from 'react'
2
- import { cn } from '@/lib/utils'
3
-
4
- interface CurrencyCellProps {
5
- value: number | null | undefined
6
- currency?: string
7
- className?: string
8
- }
9
-
10
- const formatter = new Intl.NumberFormat('de-DE', {
11
- minimumFractionDigits: 2,
12
- maximumFractionDigits: 2,
13
- })
14
-
15
- const CurrencyCell = ({ value, currency = 'EUR', className }: CurrencyCellProps) => {
16
- if (value == null) return null
17
-
18
- return (
19
- <span
20
- data-slot="currency-cell"
21
- className={cn('tabular-nums text-sm text-foreground', className)}
22
- >
23
- {formatter.format(value)} {currency}
24
- </span>
25
- )
26
- }
27
-
28
- CurrencyCell.displayName = 'CurrencyCell'
29
-
30
- export { CurrencyCell }
31
- export type { CurrencyCellProps }
@@ -1,27 +0,0 @@
1
- import * as React from 'react'
2
- import { cn } from '@/lib/utils'
3
-
4
- interface DoubleTextCellProps {
5
- primary: string | null | undefined
6
- secondary: string | null | undefined
7
- className?: string
8
- }
9
-
10
- const DoubleTextCell = ({ primary, secondary, className }: DoubleTextCellProps) => (
11
- <span
12
- data-slot="double-text-cell"
13
- className={cn('flex flex-col gap-0.5', className)}
14
- >
15
- <span className="font-medium text-sm text-foreground leading-snug">
16
- {primary ?? ''}
17
- </span>
18
- <span className="text-xs text-muted-foreground leading-snug">
19
- {secondary ?? ''}
20
- </span>
21
- </span>
22
- )
23
-
24
- DoubleTextCell.displayName = 'DoubleTextCell'
25
-
26
- export { DoubleTextCell }
27
- export type { DoubleTextCellProps }
@@ -1,67 +0,0 @@
1
- import * as React from 'react'
2
- import { ChevronDown, ArrowLeftRight, Sparkles } from 'lucide-react'
3
- import { Button } from '@/components/ui/button'
4
- import { cn } from '@/lib/utils'
5
-
6
- interface ExpandButtonProps {
7
- count: number
8
- label: string
9
- icon?: string
10
- expanded?: boolean
11
- onToggle?: () => void
12
- className?: string
13
- }
14
-
15
- const iconComponents: Record<string, React.ElementType> = {
16
- arrowLeftRight: ArrowLeftRight,
17
- sparkles: Sparkles,
18
- }
19
-
20
- const ExpandButton = ({
21
- count,
22
- label,
23
- icon,
24
- expanded = false,
25
- onToggle,
26
- className,
27
- }: ExpandButtonProps) => {
28
- const LeadIcon = icon ? iconComponents[icon] : null
29
-
30
- return (
31
- <Button
32
- data-slot="expand-button"
33
- variant="outline"
34
- aria-expanded={expanded}
35
- aria-label={label}
36
- onClick={onToggle}
37
- className={cn(
38
- 'h-8 px-2.5 text-[13px] font-medium gap-1.5 whitespace-nowrap',
39
- expanded && 'border-primary text-primary bg-primary/[0.06]',
40
- className
41
- )}
42
- >
43
- {LeadIcon && (
44
- <LeadIcon
45
- size={16}
46
- className={cn('text-muted-foreground', expanded && 'text-primary')}
47
- aria-hidden="true"
48
- />
49
- )}
50
- <span>{label}</span>
51
- <span className="text-muted-foreground">{count}</span>
52
- <ChevronDown
53
- size={14}
54
- className={cn(
55
- 'text-muted-foreground transition-transform duration-200',
56
- expanded && 'rotate-180 text-primary'
57
- )}
58
- aria-hidden="true"
59
- />
60
- </Button>
61
- )
62
- }
63
-
64
- ExpandButton.displayName = 'ExpandButton'
65
-
66
- export { ExpandButton }
67
- export type { ExpandButtonProps }
@@ -1,52 +0,0 @@
1
- import * as React from 'react'
2
- import { Badge } from '@/components/ui/badge'
3
- import { cn } from '@/lib/utils'
4
-
5
- interface InventoryBadgeCellProps {
6
- value: number | null | undefined
7
- levelFn?: (value: number) => string
8
- formatFn?: (value: number) => string
9
- className?: string
10
- }
11
-
12
- const inventoryColorMap: Record<string, string> = {
13
- high: 'bg-[var(--inventory-high-bg)] text-[var(--inventory-high)] border-transparent',
14
- medium: 'bg-[var(--inventory-medium-bg)] text-[var(--inventory-medium)] border-transparent',
15
- low: 'bg-[var(--inventory-low-bg)] text-[var(--inventory-low)] border-transparent',
16
- }
17
-
18
- const defaultLevelFn = (value: number): string => {
19
- if (value > 500) return 'high'
20
- if (value > 100) return 'medium'
21
- return 'low'
22
- }
23
-
24
- const defaultFormatter = new Intl.NumberFormat('de-DE')
25
- const defaultFormatFn = (value: number): string => defaultFormatter.format(value)
26
-
27
- const InventoryBadgeCell = ({
28
- value,
29
- levelFn = defaultLevelFn,
30
- formatFn = defaultFormatFn,
31
- className,
32
- }: InventoryBadgeCellProps) => {
33
- if (value == null) return null
34
-
35
- const level = levelFn(value)
36
- const colorClass = inventoryColorMap[level] ?? inventoryColorMap['medium']
37
-
38
- return (
39
- <Badge
40
- data-slot="inventory-badge-cell"
41
- variant="outline"
42
- className={cn(colorClass, 'font-semibold tabular-nums', className)}
43
- >
44
- {formatFn(value)}
45
- </Badge>
46
- )
47
- }
48
-
49
- InventoryBadgeCell.displayName = 'InventoryBadgeCell'
50
-
51
- export { InventoryBadgeCell }
52
- export type { InventoryBadgeCellProps }
@@ -1,42 +0,0 @@
1
- import * as React from 'react'
2
- import { cn } from '@/lib/utils'
3
-
4
- interface LinkCellProps {
5
- value: string | null | undefined
6
- href?: string
7
- className?: string
8
- }
9
-
10
- const linkClasses = 'text-sm text-primary hover:underline cursor-pointer underline-offset-4'
11
-
12
- const LinkCell = ({ value, href, className }: LinkCellProps) => {
13
- const text = value ?? ''
14
-
15
- if (href) {
16
- return (
17
- <a
18
- data-slot="link-cell"
19
- href={href}
20
- className={cn(linkClasses, className)}
21
- >
22
- {text}
23
- </a>
24
- )
25
- }
26
-
27
- return (
28
- <span
29
- data-slot="link-cell"
30
- role="link"
31
- tabIndex={0}
32
- className={cn(linkClasses, className)}
33
- >
34
- {text}
35
- </span>
36
- )
37
- }
38
-
39
- LinkCell.displayName = 'LinkCell'
40
-
41
- export { LinkCell }
42
- export type { LinkCellProps }
@@ -1,50 +0,0 @@
1
- import * as React from 'react'
2
- import { cn } from '@/lib/utils'
3
-
4
- interface ScoreBarProps {
5
- value: number
6
- className?: string
7
- }
8
-
9
- const getIndicatorColor = (value: number): string => {
10
- if (value >= 70) return 'var(--color-success)'
11
- if (value >= 40) return 'var(--color-warning)'
12
- return 'var(--color-alert)'
13
- }
14
-
15
- const ScoreBar = ({ value, className }: ScoreBarProps) => {
16
- const clamped = Math.max(0, Math.min(100, value))
17
- const indicatorColor = getIndicatorColor(clamped)
18
-
19
- return (
20
- <div
21
- data-slot="score-bar"
22
- className={cn('flex items-center gap-2', className)}
23
- >
24
- {/* Custom progress track — shadcn Progress locks indicator to bg-primary, so we render directly */}
25
- <div
26
- role="progressbar"
27
- aria-valuenow={clamped}
28
- aria-valuemin={0}
29
- aria-valuemax={100}
30
- className="flex-1 max-w-[120px] h-1.5 rounded-full bg-border overflow-hidden"
31
- >
32
- <div
33
- className="h-full rounded-full transition-all"
34
- style={{
35
- width: `${clamped}%`,
36
- backgroundColor: indicatorColor,
37
- }}
38
- />
39
- </div>
40
- <span className="tabular-nums text-xs font-semibold w-9 text-right">
41
- {clamped}%
42
- </span>
43
- </div>
44
- )
45
- }
46
-
47
- ScoreBar.displayName = 'ScoreBar'
48
-
49
- export { ScoreBar }
50
- export type { ScoreBarProps }
@@ -1,39 +0,0 @@
1
- import * as React from 'react'
2
- import { Badge } from '@/components/ui/badge'
3
- import { cn } from '@/lib/utils'
4
-
5
- interface StatusBadgeCellProps {
6
- value: string | null | undefined
7
- statusMap?: Record<string, string>
8
- className?: string
9
- }
10
-
11
- const statusColorMap: Record<string, string> = {
12
- active: 'bg-[var(--lifecycle-active-bg)] text-[var(--lifecycle-active)] border-transparent',
13
- nrnd: 'bg-[var(--lifecycle-nrnd-bg)] text-[var(--lifecycle-nrnd)] border-transparent',
14
- eol: 'bg-[var(--lifecycle-eol-bg)] text-[var(--lifecycle-eol)] border-transparent',
15
- production: 'bg-[var(--lifecycle-production-bg)] text-[var(--lifecycle-production)] border-transparent',
16
- }
17
-
18
- const StatusBadgeCell = ({ value, statusMap, className }: StatusBadgeCellProps) => {
19
- if (value == null || value === '') return null
20
-
21
- const statusKey = statusMap?.[value] ?? value.toLowerCase()
22
- const colorClass = statusColorMap[statusKey] ?? statusColorMap['active']
23
-
24
- return (
25
- <Badge
26
- data-slot="status-badge-cell"
27
- variant="outline"
28
- className={cn(colorClass, 'gap-1.5 px-2.5 py-1', className)}
29
- >
30
- <span className="size-1.5 rounded-full bg-current" aria-hidden="true" />
31
- {value}
32
- </Badge>
33
- )
34
- }
35
-
36
- StatusBadgeCell.displayName = 'StatusBadgeCell'
37
-
38
- export { StatusBadgeCell }
39
- export type { StatusBadgeCellProps }
@@ -1,35 +0,0 @@
1
- import * as React from 'react'
2
- import { cn } from '@/lib/utils'
3
-
4
- interface TextCellProps {
5
- value: string | null | undefined
6
- maxLines?: number
7
- className?: string
8
- }
9
-
10
- const lineClampMap: Record<number, string> = {
11
- 1: 'line-clamp-1',
12
- 2: 'line-clamp-2',
13
- 3: 'line-clamp-3',
14
- 4: 'line-clamp-4',
15
- 5: 'line-clamp-5',
16
- 6: 'line-clamp-6',
17
- }
18
-
19
- const TextCell = ({ value, maxLines, className }: TextCellProps) => (
20
- <span
21
- data-slot="text-cell"
22
- className={cn(
23
- 'text-sm text-foreground',
24
- maxLines != null && lineClampMap[maxLines],
25
- className
26
- )}
27
- >
28
- {value ?? ''}
29
- </span>
30
- )
31
-
32
- TextCell.displayName = 'TextCell'
33
-
34
- export { TextCell }
35
- export type { TextCellProps }
@@ -1,26 +0,0 @@
1
- export { TextCell } from './TextCell'
2
- export type { TextCellProps } from './TextCell'
3
-
4
- export { DoubleTextCell } from './DoubleTextCell'
5
- export type { DoubleTextCellProps } from './DoubleTextCell'
6
-
7
- export { LinkCell } from './LinkCell'
8
- export type { LinkCellProps } from './LinkCell'
9
-
10
- export { StatusBadgeCell } from './StatusBadgeCell'
11
- export type { StatusBadgeCellProps } from './StatusBadgeCell'
12
-
13
- export { CurrencyCell } from './CurrencyCell'
14
- export type { CurrencyCellProps } from './CurrencyCell'
15
-
16
- export { InventoryBadgeCell } from './InventoryBadgeCell'
17
- export type { InventoryBadgeCellProps } from './InventoryBadgeCell'
18
-
19
- export { ScoreBar } from './ScoreBar'
20
- export type { ScoreBarProps } from './ScoreBar'
21
-
22
- export { ExpandButton } from './ExpandButton'
23
- export type { ExpandButtonProps } from './ExpandButton'
24
-
25
- export { CellRenderer } from './CellRenderer'
26
- export type { CellRendererProps } from './CellRenderer'