@dilipod/ui 0.3.2 → 0.3.4
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/dist/components/error-state.d.ts +26 -0
- package/dist/components/error-state.d.ts.map +1 -0
- package/dist/components/metric-label.d.ts +60 -0
- package/dist/components/metric-label.d.ts.map +1 -0
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +266 -124
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +261 -123
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/error-state.tsx +118 -0
- package/src/components/metric-label.tsx +135 -0
- package/src/components/tabs.tsx +3 -1
- package/src/index.ts +8 -5
package/package.json
CHANGED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { Card, CardContent } from './card'
|
|
5
|
+
import { IconBox } from './icon-box'
|
|
6
|
+
import { Button } from './button'
|
|
7
|
+
import { cn } from '../lib/utils'
|
|
8
|
+
|
|
9
|
+
export interface ErrorStateProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
10
|
+
/** Title text */
|
|
11
|
+
title?: string
|
|
12
|
+
/** Description text */
|
|
13
|
+
description?: string
|
|
14
|
+
/** Whether to show the retry button */
|
|
15
|
+
showRetry?: boolean
|
|
16
|
+
/** Whether to show the home/dashboard link */
|
|
17
|
+
showHomeLink?: boolean
|
|
18
|
+
/** Custom retry button text */
|
|
19
|
+
retryText?: string
|
|
20
|
+
/** Custom home link text */
|
|
21
|
+
homeLinkText?: string
|
|
22
|
+
/** Callback when retry is clicked */
|
|
23
|
+
onRetry?: () => void
|
|
24
|
+
/** Callback when home link is clicked */
|
|
25
|
+
onHomeClick?: () => void
|
|
26
|
+
/** Custom icon to display */
|
|
27
|
+
icon?: React.ReactNode
|
|
28
|
+
/** Custom action buttons */
|
|
29
|
+
actions?: React.ReactNode
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const ErrorState = React.forwardRef<HTMLDivElement, ErrorStateProps>(
|
|
33
|
+
(
|
|
34
|
+
{
|
|
35
|
+
title = 'Something went wrong',
|
|
36
|
+
description = 'We encountered an error loading this page. Please try again.',
|
|
37
|
+
showRetry = true,
|
|
38
|
+
showHomeLink = true,
|
|
39
|
+
retryText = 'Try again',
|
|
40
|
+
homeLinkText = 'Go to dashboard',
|
|
41
|
+
onRetry,
|
|
42
|
+
onHomeClick,
|
|
43
|
+
icon,
|
|
44
|
+
actions,
|
|
45
|
+
className,
|
|
46
|
+
...props
|
|
47
|
+
},
|
|
48
|
+
ref
|
|
49
|
+
) => {
|
|
50
|
+
// Default icon - Warning icon
|
|
51
|
+
const defaultIcon = (
|
|
52
|
+
<svg
|
|
53
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
54
|
+
width="24"
|
|
55
|
+
height="24"
|
|
56
|
+
fill="currentColor"
|
|
57
|
+
viewBox="0 0 256 256"
|
|
58
|
+
className="text-red-500"
|
|
59
|
+
>
|
|
60
|
+
<path d="M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM120,104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm8,88a12,12,0,1,1,12-12A12,12,0,0,1,128,192Z" />
|
|
61
|
+
</svg>
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
// Default refresh icon for retry button
|
|
65
|
+
const refreshIcon = (
|
|
66
|
+
<svg
|
|
67
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
68
|
+
width="16"
|
|
69
|
+
height="16"
|
|
70
|
+
fill="currentColor"
|
|
71
|
+
viewBox="0 0 256 256"
|
|
72
|
+
className="mr-2"
|
|
73
|
+
>
|
|
74
|
+
<path d="M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64A80,80,0,1,0,207.6,176.16a8,8,0,1,1,13.54,8.49A96,96,0,1,1,227.59,64l.3-.31L208,44.31V56a8,8,0,0,0,8,8h16A8,8,0,0,0,240,56Z" />
|
|
75
|
+
</svg>
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const hasDefaultActions = (showRetry && onRetry) || (showHomeLink && onHomeClick)
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div
|
|
82
|
+
ref={ref}
|
|
83
|
+
className={cn('flex items-center justify-center min-h-[60vh]', className)}
|
|
84
|
+
{...props}
|
|
85
|
+
>
|
|
86
|
+
<Card className="max-w-md w-full">
|
|
87
|
+
<CardContent className="p-8 text-center">
|
|
88
|
+
<IconBox size="lg" className="mx-auto mb-4 bg-red-50">
|
|
89
|
+
{icon || defaultIcon}
|
|
90
|
+
</IconBox>
|
|
91
|
+
<h2 className="text-lg font-semibold text-[var(--black)] mb-2">
|
|
92
|
+
{title}
|
|
93
|
+
</h2>
|
|
94
|
+
<p className="text-sm text-muted-foreground mb-6">{description}</p>
|
|
95
|
+
{actions ? (
|
|
96
|
+
<div className="flex gap-3 justify-center">{actions}</div>
|
|
97
|
+
) : hasDefaultActions ? (
|
|
98
|
+
<div className="flex gap-3 justify-center">
|
|
99
|
+
{showRetry && onRetry && (
|
|
100
|
+
<Button variant="outline" onClick={onRetry}>
|
|
101
|
+
{refreshIcon}
|
|
102
|
+
{retryText}
|
|
103
|
+
</Button>
|
|
104
|
+
)}
|
|
105
|
+
{showHomeLink && onHomeClick && (
|
|
106
|
+
<Button onClick={onHomeClick}>{homeLinkText}</Button>
|
|
107
|
+
)}
|
|
108
|
+
</div>
|
|
109
|
+
) : null}
|
|
110
|
+
</CardContent>
|
|
111
|
+
</Card>
|
|
112
|
+
</div>
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
ErrorState.displayName = 'ErrorState'
|
|
117
|
+
|
|
118
|
+
export { ErrorState }
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { cn } from '../lib/utils'
|
|
5
|
+
|
|
6
|
+
export interface MetricLabelProps extends React.HTMLAttributes<HTMLParagraphElement> {
|
|
7
|
+
/** The label text */
|
|
8
|
+
children: React.ReactNode
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* MetricLabel - A utility component for consistent metric labeling
|
|
13
|
+
*
|
|
14
|
+
* Uses the standardized pattern: text-xs uppercase tracking-wide text-muted-foreground
|
|
15
|
+
* Typically used above metric values in dashboards and cards.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <MetricLabel>Monthly Revenue</MetricLabel>
|
|
19
|
+
* <p className="text-2xl font-bold">€5,000</p>
|
|
20
|
+
*/
|
|
21
|
+
const MetricLabel = React.forwardRef<HTMLParagraphElement, MetricLabelProps>(
|
|
22
|
+
({ className, children, ...props }, ref) => {
|
|
23
|
+
return (
|
|
24
|
+
<p
|
|
25
|
+
ref={ref}
|
|
26
|
+
className={cn(
|
|
27
|
+
'text-xs text-muted-foreground uppercase tracking-wide',
|
|
28
|
+
className
|
|
29
|
+
)}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
{children}
|
|
33
|
+
</p>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
MetricLabel.displayName = 'MetricLabel'
|
|
38
|
+
|
|
39
|
+
export interface MetricValueProps extends React.HTMLAttributes<HTMLParagraphElement> {
|
|
40
|
+
/** The value to display */
|
|
41
|
+
children: React.ReactNode
|
|
42
|
+
/** Size variant */
|
|
43
|
+
size?: 'default' | 'lg' | 'sm'
|
|
44
|
+
/** Highlight the value (uses brand cyan) */
|
|
45
|
+
highlight?: boolean
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* MetricValue - A utility component for consistent metric value display
|
|
50
|
+
*
|
|
51
|
+
* Pairs with MetricLabel for a complete metric display pattern.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* <MetricLabel>Monthly Revenue</MetricLabel>
|
|
55
|
+
* <MetricValue highlight>€5,000</MetricValue>
|
|
56
|
+
*/
|
|
57
|
+
const MetricValue = React.forwardRef<HTMLParagraphElement, MetricValueProps>(
|
|
58
|
+
({ className, children, size = 'default', highlight = false, ...props }, ref) => {
|
|
59
|
+
return (
|
|
60
|
+
<p
|
|
61
|
+
ref={ref}
|
|
62
|
+
className={cn(
|
|
63
|
+
'font-bold mt-1',
|
|
64
|
+
size === 'lg' && 'text-3xl',
|
|
65
|
+
size === 'default' && 'text-2xl',
|
|
66
|
+
size === 'sm' && 'text-xl',
|
|
67
|
+
highlight && 'text-[#00e5cc]',
|
|
68
|
+
className
|
|
69
|
+
)}
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
{children}
|
|
73
|
+
</p>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
MetricValue.displayName = 'MetricValue'
|
|
78
|
+
|
|
79
|
+
export interface MetricSubtextProps extends React.HTMLAttributes<HTMLParagraphElement> {
|
|
80
|
+
/** The subtext content */
|
|
81
|
+
children: React.ReactNode
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* MetricSubtext - A utility component for metric subtitles/descriptions
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* <MetricLabel>Monthly Revenue</MetricLabel>
|
|
89
|
+
* <MetricValue>€5,000</MetricValue>
|
|
90
|
+
* <MetricSubtext>ARR: €60,000</MetricSubtext>
|
|
91
|
+
*/
|
|
92
|
+
const MetricSubtext = React.forwardRef<HTMLParagraphElement, MetricSubtextProps>(
|
|
93
|
+
({ className, children, ...props }, ref) => {
|
|
94
|
+
return (
|
|
95
|
+
<p
|
|
96
|
+
ref={ref}
|
|
97
|
+
className={cn(
|
|
98
|
+
'text-xs text-muted-foreground mt-1',
|
|
99
|
+
className
|
|
100
|
+
)}
|
|
101
|
+
{...props}
|
|
102
|
+
>
|
|
103
|
+
{children}
|
|
104
|
+
</p>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
MetricSubtext.displayName = 'MetricSubtext'
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Metric - A compound component combining Label, Value, and optional Subtext
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* <Metric>
|
|
115
|
+
* <MetricLabel>Monthly Revenue</MetricLabel>
|
|
116
|
+
* <MetricValue highlight>€5,000</MetricValue>
|
|
117
|
+
* <MetricSubtext>ARR: €60,000</MetricSubtext>
|
|
118
|
+
* </Metric>
|
|
119
|
+
*/
|
|
120
|
+
const Metric = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
121
|
+
({ className, children, ...props }, ref) => {
|
|
122
|
+
return (
|
|
123
|
+
<div
|
|
124
|
+
ref={ref}
|
|
125
|
+
className={cn(className)}
|
|
126
|
+
{...props}
|
|
127
|
+
>
|
|
128
|
+
{children}
|
|
129
|
+
</div>
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
Metric.displayName = 'Metric'
|
|
134
|
+
|
|
135
|
+
export { MetricLabel, MetricValue, MetricSubtext, Metric }
|
package/src/components/tabs.tsx
CHANGED
|
@@ -74,7 +74,9 @@ const TabsTriggerUnderline = React.forwardRef<
|
|
|
74
74
|
<TabsPrimitive.Trigger
|
|
75
75
|
ref={ref}
|
|
76
76
|
className={cn(
|
|
77
|
-
'inline-flex items-center justify-center whitespace-nowrap px-4 py-2 text-sm font-medium text-muted-foreground transition-
|
|
77
|
+
'inline-flex items-center justify-center whitespace-nowrap px-4 py-2.5 text-sm font-medium text-muted-foreground transition-all hover:text-foreground border-b-2 border-transparent -mb-px',
|
|
78
|
+
'data-[state=active]:text-[var(--cyan)] data-[state=active]:border-[var(--cyan)] data-[state=active]:font-semibold',
|
|
79
|
+
'disabled:pointer-events-none disabled:opacity-50',
|
|
78
80
|
className
|
|
79
81
|
)}
|
|
80
82
|
{...props}
|
package/src/index.ts
CHANGED
|
@@ -46,6 +46,9 @@ export type { StatProps } from './components/stat'
|
|
|
46
46
|
export { MetricCard, metricCardVariants } from './components/metric-card'
|
|
47
47
|
export type { MetricCardProps } from './components/metric-card'
|
|
48
48
|
|
|
49
|
+
export { MetricLabel, MetricValue, MetricSubtext, Metric } from './components/metric-label'
|
|
50
|
+
export type { MetricLabelProps, MetricValueProps, MetricSubtextProps } from './components/metric-label'
|
|
51
|
+
|
|
49
52
|
export { UsageBar, usageBarVariants } from './components/usage-bar'
|
|
50
53
|
export type { UsageBarProps } from './components/usage-bar'
|
|
51
54
|
|
|
@@ -121,13 +124,10 @@ export {
|
|
|
121
124
|
DropdownMenuRadioGroup,
|
|
122
125
|
} from './components/dropdown-menu'
|
|
123
126
|
|
|
124
|
-
export {
|
|
125
|
-
Sidebar,
|
|
126
|
-
SidebarNavItem,
|
|
127
|
-
} from './components/sidebar'
|
|
127
|
+
export { Sidebar } from './components/sidebar'
|
|
128
128
|
export type {
|
|
129
129
|
SidebarProps,
|
|
130
|
-
SidebarNavItem
|
|
130
|
+
SidebarNavItem,
|
|
131
131
|
SidebarNavItemProps,
|
|
132
132
|
} from './components/sidebar'
|
|
133
133
|
|
|
@@ -137,6 +137,9 @@ export type { AlertProps } from './components/alert'
|
|
|
137
137
|
export { EmptyState } from './components/empty-state'
|
|
138
138
|
export type { EmptyStateProps } from './components/empty-state'
|
|
139
139
|
|
|
140
|
+
export { ErrorState } from './components/error-state'
|
|
141
|
+
export type { ErrorStateProps } from './components/error-state'
|
|
142
|
+
|
|
140
143
|
export { CodeBlock } from './components/code-block'
|
|
141
144
|
export type { CodeBlockProps } from './components/code-block'
|
|
142
145
|
|