@dilipod/ui 0.1.0
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/README.md +226 -0
- package/dist/index.d.mts +133 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +888 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +552 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +89 -0
- package/src/components/badge.stories.tsx +99 -0
- package/src/components/badge.tsx +86 -0
- package/src/components/button.stories.tsx +136 -0
- package/src/components/button.tsx +63 -0
- package/src/components/card.stories.tsx +107 -0
- package/src/components/card.tsx +80 -0
- package/src/components/icon-box.stories.tsx +99 -0
- package/src/components/icon-box.tsx +57 -0
- package/src/components/logo.stories.tsx +93 -0
- package/src/components/logo.tsx +91 -0
- package/src/components/progress.stories.tsx +99 -0
- package/src/components/progress.tsx +70 -0
- package/src/components/sheet.stories.tsx +109 -0
- package/src/components/sheet.tsx +140 -0
- package/src/components/stat.stories.tsx +127 -0
- package/src/components/stat.tsx +115 -0
- package/src/components/tag.stories.tsx +107 -0
- package/src/components/tag.tsx +53 -0
- package/src/icons.ts +107 -0
- package/src/index.ts +50 -0
- package/src/lib/utils.ts +6 -0
- package/src/styles/globals.css +187 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import * as SheetPrimitive from '@radix-ui/react-dialog'
|
|
5
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
6
|
+
import { X } from '@phosphor-icons/react'
|
|
7
|
+
|
|
8
|
+
import { cn } from '../lib/utils'
|
|
9
|
+
|
|
10
|
+
const Sheet = SheetPrimitive.Root
|
|
11
|
+
|
|
12
|
+
const SheetTrigger = SheetPrimitive.Trigger
|
|
13
|
+
|
|
14
|
+
const SheetClose = SheetPrimitive.Close
|
|
15
|
+
|
|
16
|
+
const SheetPortal = SheetPrimitive.Portal
|
|
17
|
+
|
|
18
|
+
const SheetOverlay = React.forwardRef<
|
|
19
|
+
React.ElementRef<typeof SheetPrimitive.Overlay>,
|
|
20
|
+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
|
|
21
|
+
>(({ className, ...props }, ref) => (
|
|
22
|
+
<SheetPrimitive.Overlay
|
|
23
|
+
className={cn(
|
|
24
|
+
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
25
|
+
className
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
ref={ref}
|
|
29
|
+
/>
|
|
30
|
+
))
|
|
31
|
+
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
|
|
32
|
+
|
|
33
|
+
const sheetVariants = cva(
|
|
34
|
+
'fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
|
35
|
+
{
|
|
36
|
+
variants: {
|
|
37
|
+
side: {
|
|
38
|
+
top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
|
|
39
|
+
bottom:
|
|
40
|
+
'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
|
|
41
|
+
left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',
|
|
42
|
+
right:
|
|
43
|
+
'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
defaultVariants: {
|
|
47
|
+
side: 'right',
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
interface SheetContentProps
|
|
53
|
+
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
|
|
54
|
+
VariantProps<typeof sheetVariants> {}
|
|
55
|
+
|
|
56
|
+
const SheetContent = React.forwardRef<
|
|
57
|
+
React.ElementRef<typeof SheetPrimitive.Content>,
|
|
58
|
+
SheetContentProps
|
|
59
|
+
>(({ side = 'right', className, children, ...props }, ref) => (
|
|
60
|
+
<SheetPortal>
|
|
61
|
+
<SheetOverlay />
|
|
62
|
+
<SheetPrimitive.Content
|
|
63
|
+
ref={ref}
|
|
64
|
+
className={cn(sheetVariants({ side }), className)}
|
|
65
|
+
{...props}
|
|
66
|
+
>
|
|
67
|
+
{children}
|
|
68
|
+
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[var(--cyan)] focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-gray-100">
|
|
69
|
+
<X className="h-4 w-4" />
|
|
70
|
+
<span className="sr-only">Close</span>
|
|
71
|
+
</SheetPrimitive.Close>
|
|
72
|
+
</SheetPrimitive.Content>
|
|
73
|
+
</SheetPortal>
|
|
74
|
+
))
|
|
75
|
+
SheetContent.displayName = SheetPrimitive.Content.displayName
|
|
76
|
+
|
|
77
|
+
const SheetHeader = ({
|
|
78
|
+
className,
|
|
79
|
+
...props
|
|
80
|
+
}: React.HTMLAttributes<HTMLDivElement>) => (
|
|
81
|
+
<div
|
|
82
|
+
className={cn(
|
|
83
|
+
'flex flex-col space-y-2 text-center sm:text-left',
|
|
84
|
+
className
|
|
85
|
+
)}
|
|
86
|
+
{...props}
|
|
87
|
+
/>
|
|
88
|
+
)
|
|
89
|
+
SheetHeader.displayName = 'SheetHeader'
|
|
90
|
+
|
|
91
|
+
const SheetFooter = ({
|
|
92
|
+
className,
|
|
93
|
+
...props
|
|
94
|
+
}: React.HTMLAttributes<HTMLDivElement>) => (
|
|
95
|
+
<div
|
|
96
|
+
className={cn(
|
|
97
|
+
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
|
|
98
|
+
className
|
|
99
|
+
)}
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
)
|
|
103
|
+
SheetFooter.displayName = 'SheetFooter'
|
|
104
|
+
|
|
105
|
+
const SheetTitle = React.forwardRef<
|
|
106
|
+
React.ElementRef<typeof SheetPrimitive.Title>,
|
|
107
|
+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
|
|
108
|
+
>(({ className, ...props }, ref) => (
|
|
109
|
+
<SheetPrimitive.Title
|
|
110
|
+
ref={ref}
|
|
111
|
+
className={cn('text-lg font-semibold text-[var(--black)]', className)}
|
|
112
|
+
{...props}
|
|
113
|
+
/>
|
|
114
|
+
))
|
|
115
|
+
SheetTitle.displayName = SheetPrimitive.Title.displayName
|
|
116
|
+
|
|
117
|
+
const SheetDescription = React.forwardRef<
|
|
118
|
+
React.ElementRef<typeof SheetPrimitive.Description>,
|
|
119
|
+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
|
|
120
|
+
>(({ className, ...props }, ref) => (
|
|
121
|
+
<SheetPrimitive.Description
|
|
122
|
+
ref={ref}
|
|
123
|
+
className={cn('text-sm text-gray-500', className)}
|
|
124
|
+
{...props}
|
|
125
|
+
/>
|
|
126
|
+
))
|
|
127
|
+
SheetDescription.displayName = SheetPrimitive.Description.displayName
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
Sheet,
|
|
131
|
+
SheetPortal,
|
|
132
|
+
SheetOverlay,
|
|
133
|
+
SheetTrigger,
|
|
134
|
+
SheetClose,
|
|
135
|
+
SheetContent,
|
|
136
|
+
SheetHeader,
|
|
137
|
+
SheetFooter,
|
|
138
|
+
SheetTitle,
|
|
139
|
+
SheetDescription,
|
|
140
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { Stat } from './stat'
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Stat> = {
|
|
5
|
+
title: 'Components/Stat',
|
|
6
|
+
component: Stat,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
argTypes: {
|
|
9
|
+
variant: {
|
|
10
|
+
control: 'select',
|
|
11
|
+
options: ['default', 'card'],
|
|
12
|
+
},
|
|
13
|
+
align: {
|
|
14
|
+
control: 'select',
|
|
15
|
+
options: ['left', 'center', 'right'],
|
|
16
|
+
},
|
|
17
|
+
valueSize: {
|
|
18
|
+
control: 'select',
|
|
19
|
+
options: ['sm', 'default', 'lg', 'xl'],
|
|
20
|
+
},
|
|
21
|
+
valueColor: {
|
|
22
|
+
control: 'select',
|
|
23
|
+
options: ['default', 'primary', 'white', 'gradient'],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default meta
|
|
29
|
+
type Story = StoryObj<typeof Stat>
|
|
30
|
+
|
|
31
|
+
export const Default: Story = {
|
|
32
|
+
args: {
|
|
33
|
+
value: '1,247',
|
|
34
|
+
label: 'Docs Reviewed',
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const WithSuffix: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
value: '80%',
|
|
41
|
+
suffix: 'cheaper',
|
|
42
|
+
label: '€6-12K/year vs €40-60K for an employee',
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const Primary: Story = {
|
|
47
|
+
args: {
|
|
48
|
+
value: '99.8%',
|
|
49
|
+
label: 'Accuracy',
|
|
50
|
+
valueColor: 'primary',
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const Large: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
value: '24h',
|
|
57
|
+
suffix: 'to deploy',
|
|
58
|
+
label: 'From call to working agent in one day',
|
|
59
|
+
valueSize: 'lg',
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const Card: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
value: '1,247',
|
|
66
|
+
label: 'Docs Reviewed',
|
|
67
|
+
variant: 'card',
|
|
68
|
+
align: 'center',
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const Centered: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
value: '24/7',
|
|
75
|
+
label: 'Available',
|
|
76
|
+
align: 'center',
|
|
77
|
+
valueColor: 'primary',
|
|
78
|
+
valueSize: 'lg',
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const StatsGrid: Story = {
|
|
83
|
+
render: () => (
|
|
84
|
+
<div className="grid grid-cols-2 gap-4 w-80">
|
|
85
|
+
<Stat value="1,247" label="Docs Reviewed" variant="card" align="center" />
|
|
86
|
+
<Stat value="99.8%" label="Accuracy" variant="card" align="center" valueColor="primary" />
|
|
87
|
+
</div>
|
|
88
|
+
),
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const SolutionStats: Story = {
|
|
92
|
+
render: () => (
|
|
93
|
+
<div className="grid grid-cols-4 gap-8">
|
|
94
|
+
<Stat value="80%" suffix="cheaper" label="€6-12K/year vs €40-60K" valueSize="lg" />
|
|
95
|
+
<Stat value="24h" suffix="to deploy" label="From call to working agent" valueSize="lg" />
|
|
96
|
+
<Stat value="Zero" suffix="maintenance" label="We handle everything" valueSize="lg" />
|
|
97
|
+
<Stat value="Instant" suffix="capacity" label="Add more agents on demand" valueSize="lg" />
|
|
98
|
+
</div>
|
|
99
|
+
),
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const UseCaseStats: Story = {
|
|
103
|
+
render: () => (
|
|
104
|
+
<div className="flex gap-8">
|
|
105
|
+
<Stat value="40hrs" label="saved/week" valueColor="primary" />
|
|
106
|
+
<Stat value="99.8%" label="accuracy" valueColor="primary" />
|
|
107
|
+
<Stat value="10x" label="faster" valueColor="primary" />
|
|
108
|
+
<Stat value="24/7" label="available" valueColor="primary" />
|
|
109
|
+
</div>
|
|
110
|
+
),
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export const OnDarkBackground: Story = {
|
|
114
|
+
render: () => (
|
|
115
|
+
<div className="bg-[var(--black)] p-8 rounded-lg">
|
|
116
|
+
<div className="grid grid-cols-4 gap-8">
|
|
117
|
+
<Stat value="80%" suffix="cheaper" valueSize="lg" valueColor="white" />
|
|
118
|
+
<Stat value="24h" suffix="to deploy" valueSize="lg" valueColor="white" />
|
|
119
|
+
<Stat value="Zero" suffix="maintenance" valueSize="lg" valueColor="white" />
|
|
120
|
+
<Stat value="Instant" suffix="capacity" valueSize="lg" valueColor="white" />
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
),
|
|
124
|
+
parameters: {
|
|
125
|
+
backgrounds: { default: 'dark' },
|
|
126
|
+
},
|
|
127
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
5
|
+
import { cn } from '../lib/utils'
|
|
6
|
+
|
|
7
|
+
const statVariants = cva('', {
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: '',
|
|
11
|
+
card: 'p-3 rounded-sm bg-gray-50 text-center',
|
|
12
|
+
},
|
|
13
|
+
align: {
|
|
14
|
+
left: 'text-left',
|
|
15
|
+
center: 'text-center',
|
|
16
|
+
right: 'text-right',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
defaultVariants: {
|
|
20
|
+
variant: 'default',
|
|
21
|
+
align: 'left',
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const valueVariants = cva('font-bold', {
|
|
26
|
+
variants: {
|
|
27
|
+
size: {
|
|
28
|
+
sm: 'text-xl',
|
|
29
|
+
default: 'text-3xl md:text-4xl',
|
|
30
|
+
lg: 'text-4xl md:text-5xl',
|
|
31
|
+
xl: 'text-5xl md:text-6xl',
|
|
32
|
+
},
|
|
33
|
+
color: {
|
|
34
|
+
default: 'text-[var(--black)]',
|
|
35
|
+
primary: 'text-[var(--cyan)]',
|
|
36
|
+
white: 'text-white',
|
|
37
|
+
gradient: 'text-gradient',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
defaultVariants: {
|
|
41
|
+
size: 'default',
|
|
42
|
+
color: 'default',
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
export interface StatProps
|
|
47
|
+
extends React.HTMLAttributes<HTMLDivElement>,
|
|
48
|
+
VariantProps<typeof statVariants> {
|
|
49
|
+
/** The main value to display */
|
|
50
|
+
value: string | number
|
|
51
|
+
/** Label below the value */
|
|
52
|
+
label?: string
|
|
53
|
+
/** Optional suffix after value (e.g., "faster", "cheaper") */
|
|
54
|
+
suffix?: string
|
|
55
|
+
/** Size of the value text */
|
|
56
|
+
valueSize?: 'sm' | 'default' | 'lg' | 'xl'
|
|
57
|
+
/** Color of the value */
|
|
58
|
+
valueColor?: 'default' | 'primary' | 'white' | 'gradient'
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const Stat = React.forwardRef<HTMLDivElement, StatProps>(
|
|
62
|
+
(
|
|
63
|
+
{
|
|
64
|
+
className,
|
|
65
|
+
variant,
|
|
66
|
+
align,
|
|
67
|
+
value,
|
|
68
|
+
label,
|
|
69
|
+
suffix,
|
|
70
|
+
valueSize = 'default',
|
|
71
|
+
valueColor = 'default',
|
|
72
|
+
...props
|
|
73
|
+
},
|
|
74
|
+
ref
|
|
75
|
+
) => {
|
|
76
|
+
const justifyClass = {
|
|
77
|
+
left: 'justify-start',
|
|
78
|
+
center: 'justify-center',
|
|
79
|
+
right: 'justify-end',
|
|
80
|
+
}[align || 'left']
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<div
|
|
84
|
+
ref={ref}
|
|
85
|
+
className={cn(statVariants({ variant, align }), className)}
|
|
86
|
+
{...props}
|
|
87
|
+
>
|
|
88
|
+
<div className={cn('flex items-baseline gap-2', justifyClass)}>
|
|
89
|
+
<span className={cn(valueVariants({ size: valueSize, color: valueColor }))}>
|
|
90
|
+
{value}
|
|
91
|
+
</span>
|
|
92
|
+
{suffix && (
|
|
93
|
+
<span className={cn(
|
|
94
|
+
"font-medium text-[var(--cyan)]",
|
|
95
|
+
valueSize === 'lg' || valueSize === 'xl' ? 'text-lg md:text-xl' : 'text-base md:text-lg'
|
|
96
|
+
)}>
|
|
97
|
+
{suffix}
|
|
98
|
+
</span>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
{label && (
|
|
102
|
+
<div className={cn(
|
|
103
|
+
"font-medium mt-1",
|
|
104
|
+
valueColor === 'white' ? 'text-white/70 text-sm md:text-base' : 'text-gray-500 text-xs md:text-sm'
|
|
105
|
+
)}>
|
|
106
|
+
{label}
|
|
107
|
+
</div>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
Stat.displayName = 'Stat'
|
|
114
|
+
|
|
115
|
+
export { Stat, statVariants, valueVariants }
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { Buildings, Briefcase, FirstAid, ShoppingCart } from '@phosphor-icons/react'
|
|
3
|
+
import { Tag } from './tag'
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Tag> = {
|
|
6
|
+
title: 'Components/Tag',
|
|
7
|
+
component: Tag,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
argTypes: {
|
|
10
|
+
variant: {
|
|
11
|
+
control: 'select',
|
|
12
|
+
options: ['default', 'primary', 'outline', 'dark'],
|
|
13
|
+
},
|
|
14
|
+
size: {
|
|
15
|
+
control: 'select',
|
|
16
|
+
options: ['sm', 'default', 'lg'],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default meta
|
|
22
|
+
type Story = StoryObj<typeof Tag>
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
args: {
|
|
26
|
+
children: 'Tag Label',
|
|
27
|
+
variant: 'default',
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const Primary: Story = {
|
|
32
|
+
args: {
|
|
33
|
+
children: 'Active',
|
|
34
|
+
variant: 'primary',
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const Outline: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
children: 'Real Estate',
|
|
41
|
+
variant: 'outline',
|
|
42
|
+
icon: <Buildings size={14} weight="fill" />,
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const Dark: Story = {
|
|
47
|
+
args: {
|
|
48
|
+
children: 'Premium',
|
|
49
|
+
variant: 'dark',
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const WithIcon: Story = {
|
|
54
|
+
args: {
|
|
55
|
+
children: 'Healthcare',
|
|
56
|
+
variant: 'outline',
|
|
57
|
+
icon: <FirstAid size={14} weight="fill" />,
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const Sizes: Story = {
|
|
62
|
+
render: () => (
|
|
63
|
+
<div className="flex gap-2 items-center">
|
|
64
|
+
<Tag size="sm">Small</Tag>
|
|
65
|
+
<Tag size="default">Default</Tag>
|
|
66
|
+
<Tag size="lg">Large</Tag>
|
|
67
|
+
</div>
|
|
68
|
+
),
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const Industries: Story = {
|
|
72
|
+
render: () => (
|
|
73
|
+
<div className="flex flex-wrap gap-2">
|
|
74
|
+
<Tag variant="outline" icon={<Buildings size={14} weight="fill" />}>Real Estate</Tag>
|
|
75
|
+
<Tag variant="outline" icon={<Briefcase size={14} weight="fill" />}>Professional Services</Tag>
|
|
76
|
+
<Tag variant="outline" icon={<FirstAid size={14} weight="fill" />}>Healthcare</Tag>
|
|
77
|
+
<Tag variant="outline" icon={<ShoppingCart size={14} weight="fill" />}>E-commerce</Tag>
|
|
78
|
+
</div>
|
|
79
|
+
),
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const FeatureTags: Story = {
|
|
83
|
+
render: () => (
|
|
84
|
+
<div className="flex flex-wrap gap-2">
|
|
85
|
+
<Tag>Walk through your workflow</Tag>
|
|
86
|
+
<Tag>Show us your tools</Tag>
|
|
87
|
+
<Tag>Describe edge cases</Tag>
|
|
88
|
+
</div>
|
|
89
|
+
),
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const AllVariants: Story = {
|
|
93
|
+
render: () => (
|
|
94
|
+
<div className="flex flex-col gap-4">
|
|
95
|
+
<div className="flex gap-2 items-center flex-wrap">
|
|
96
|
+
<Tag variant="default">Default</Tag>
|
|
97
|
+
<Tag variant="primary">Primary</Tag>
|
|
98
|
+
<Tag variant="outline">Outline</Tag>
|
|
99
|
+
<Tag variant="dark">Dark</Tag>
|
|
100
|
+
</div>
|
|
101
|
+
<div className="flex gap-2 items-center flex-wrap">
|
|
102
|
+
<Tag variant="outline" icon={<Buildings size={14} weight="fill" />}>With Icon</Tag>
|
|
103
|
+
<Tag variant="primary" icon={<Briefcase size={14} weight="fill" />}>Primary Icon</Tag>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
),
|
|
107
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
5
|
+
import { cn } from '../lib/utils'
|
|
6
|
+
|
|
7
|
+
const tagVariants = cva(
|
|
8
|
+
'inline-flex items-center gap-2 font-medium transition-colors cursor-pointer',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: 'bg-gray-100 text-[var(--black)]',
|
|
13
|
+
primary: 'bg-[var(--cyan)]/10 text-[var(--cyan)]',
|
|
14
|
+
outline: 'border border-gray-200 bg-white text-gray-700 hover:border-[var(--black)] hover:text-[var(--black)]',
|
|
15
|
+
dark: 'bg-[var(--black)] text-white',
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
sm: 'px-2 py-1 text-[10px] rounded',
|
|
19
|
+
default: 'px-3 py-1.5 text-xs rounded-full',
|
|
20
|
+
lg: 'px-4 py-2 text-sm rounded-full',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: 'default',
|
|
25
|
+
size: 'default',
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
export interface TagProps
|
|
31
|
+
extends React.HTMLAttributes<HTMLSpanElement>,
|
|
32
|
+
VariantProps<typeof tagVariants> {
|
|
33
|
+
/** Optional icon to display before text */
|
|
34
|
+
icon?: React.ReactNode
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
|
|
38
|
+
({ className, variant, size, icon, children, ...props }, ref) => {
|
|
39
|
+
return (
|
|
40
|
+
<span
|
|
41
|
+
ref={ref}
|
|
42
|
+
className={cn(tagVariants({ variant, size }), className)}
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
{icon && <span className="shrink-0">{icon}</span>}
|
|
46
|
+
{children}
|
|
47
|
+
</span>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
Tag.displayName = 'Tag'
|
|
52
|
+
|
|
53
|
+
export { Tag, tagVariants }
|
package/src/icons.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dilipod Icon Library
|
|
3
|
+
*
|
|
4
|
+
* Re-exports Phosphor icons used across the design system.
|
|
5
|
+
* Import icons from '@dilipod/ui' instead of '@phosphor-icons/react' directly.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { ArrowRight, Brain, CheckCircle } from '@dilipod/ui'
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Navigation & Actions
|
|
12
|
+
export {
|
|
13
|
+
ArrowRight,
|
|
14
|
+
ArrowUpRight,
|
|
15
|
+
ArrowLeft,
|
|
16
|
+
CaretRight,
|
|
17
|
+
CaretDown,
|
|
18
|
+
CaretUp,
|
|
19
|
+
List,
|
|
20
|
+
X,
|
|
21
|
+
Plus,
|
|
22
|
+
Minus,
|
|
23
|
+
Check,
|
|
24
|
+
Play,
|
|
25
|
+
Pause,
|
|
26
|
+
Stop,
|
|
27
|
+
} from '@phosphor-icons/react'
|
|
28
|
+
|
|
29
|
+
// Business & Work
|
|
30
|
+
export {
|
|
31
|
+
Brain,
|
|
32
|
+
Robot,
|
|
33
|
+
Gear,
|
|
34
|
+
GearSix,
|
|
35
|
+
Files,
|
|
36
|
+
File,
|
|
37
|
+
FileText,
|
|
38
|
+
Database,
|
|
39
|
+
Receipt,
|
|
40
|
+
Wallet,
|
|
41
|
+
Clock,
|
|
42
|
+
Calendar,
|
|
43
|
+
VideoCamera,
|
|
44
|
+
ChatCircle,
|
|
45
|
+
ChartBar,
|
|
46
|
+
ChartLineUp,
|
|
47
|
+
Handshake,
|
|
48
|
+
UserPlus,
|
|
49
|
+
UsersThree,
|
|
50
|
+
User,
|
|
51
|
+
Users,
|
|
52
|
+
SignOut,
|
|
53
|
+
SignIn,
|
|
54
|
+
} from '@phosphor-icons/react'
|
|
55
|
+
|
|
56
|
+
// Industries
|
|
57
|
+
export {
|
|
58
|
+
Buildings,
|
|
59
|
+
Briefcase,
|
|
60
|
+
FirstAid,
|
|
61
|
+
ShoppingCart,
|
|
62
|
+
AddressBook,
|
|
63
|
+
} from '@phosphor-icons/react'
|
|
64
|
+
|
|
65
|
+
// Status & Feedback
|
|
66
|
+
export {
|
|
67
|
+
CheckCircle,
|
|
68
|
+
CheckSquare,
|
|
69
|
+
WarningCircle,
|
|
70
|
+
Warning,
|
|
71
|
+
Info,
|
|
72
|
+
Question,
|
|
73
|
+
Circle,
|
|
74
|
+
} from '@phosphor-icons/react'
|
|
75
|
+
|
|
76
|
+
// Social & Communication
|
|
77
|
+
export {
|
|
78
|
+
LinkedinLogo,
|
|
79
|
+
XLogo,
|
|
80
|
+
EnvelopeSimple,
|
|
81
|
+
Envelope,
|
|
82
|
+
Phone,
|
|
83
|
+
Globe,
|
|
84
|
+
} from '@phosphor-icons/react'
|
|
85
|
+
|
|
86
|
+
// UI Elements
|
|
87
|
+
export {
|
|
88
|
+
House,
|
|
89
|
+
MagnifyingGlass,
|
|
90
|
+
Trash,
|
|
91
|
+
PencilSimple,
|
|
92
|
+
Copy,
|
|
93
|
+
DotsThree,
|
|
94
|
+
DotsThreeVertical,
|
|
95
|
+
Eye,
|
|
96
|
+
EyeSlash,
|
|
97
|
+
Funnel,
|
|
98
|
+
SortAscending,
|
|
99
|
+
SortDescending,
|
|
100
|
+
Download,
|
|
101
|
+
Upload,
|
|
102
|
+
Link,
|
|
103
|
+
ArrowSquareOut,
|
|
104
|
+
} from '@phosphor-icons/react'
|
|
105
|
+
|
|
106
|
+
// Re-export Icon type for TypeScript
|
|
107
|
+
export type { Icon, IconProps } from '@phosphor-icons/react'
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Core Components
|
|
2
|
+
export { Button, buttonVariants } from './components/button'
|
|
3
|
+
export type { ButtonProps } from './components/button'
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
Sheet,
|
|
7
|
+
SheetPortal,
|
|
8
|
+
SheetOverlay,
|
|
9
|
+
SheetTrigger,
|
|
10
|
+
SheetClose,
|
|
11
|
+
SheetContent,
|
|
12
|
+
SheetHeader,
|
|
13
|
+
SheetFooter,
|
|
14
|
+
SheetTitle,
|
|
15
|
+
SheetDescription,
|
|
16
|
+
} from './components/sheet'
|
|
17
|
+
|
|
18
|
+
export { Logo } from './components/logo'
|
|
19
|
+
export type { LogoProps } from './components/logo'
|
|
20
|
+
|
|
21
|
+
// New Design System Components
|
|
22
|
+
export { Badge, badgeVariants } from './components/badge'
|
|
23
|
+
export type { BadgeProps } from './components/badge'
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
Card,
|
|
27
|
+
CardHeader,
|
|
28
|
+
CardFooter,
|
|
29
|
+
CardTitle,
|
|
30
|
+
CardDescription,
|
|
31
|
+
CardContent,
|
|
32
|
+
} from './components/card'
|
|
33
|
+
|
|
34
|
+
export { Progress, progressVariants } from './components/progress'
|
|
35
|
+
export type { ProgressProps } from './components/progress'
|
|
36
|
+
|
|
37
|
+
export { IconBox, iconBoxVariants } from './components/icon-box'
|
|
38
|
+
export type { IconBoxProps } from './components/icon-box'
|
|
39
|
+
|
|
40
|
+
export { Tag, tagVariants } from './components/tag'
|
|
41
|
+
export type { TagProps } from './components/tag'
|
|
42
|
+
|
|
43
|
+
export { Stat, statVariants, valueVariants } from './components/stat'
|
|
44
|
+
export type { StatProps } from './components/stat'
|
|
45
|
+
|
|
46
|
+
// Utilities
|
|
47
|
+
export { cn } from './lib/utils'
|
|
48
|
+
|
|
49
|
+
// Icons - Re-exported from @phosphor-icons/react
|
|
50
|
+
export * from './icons'
|